using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Aitex.Core.RT.Log
{
	public static class LOG
	{
		public static ICommonLog InnerLogger { private get; set; }

        public static void Debug(string message, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
        {
            InnerLogger?.Debug(message, file, member, line);
        }

		public static void Info(string message, bool isTraceOn = false, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
        {
            InnerLogger?.Info(message, isTraceOn, GetFormatStackFrameInfo(traceLevel));
        }

		private static string GetFormatStackFrameInfo(int traceLevel)
		{
			StackFrame frame = new StackTrace(fNeedFileInfo: true).GetFrame(traceLevel + 1);
			string fileName = frame.GetFileName();
			string arg = (string.IsNullOrEmpty(fileName) ? "" : fileName.Substring(fileName.LastIndexOf('\\') + 1));
			return $"{arg}\tLine {frame.GetFileLineNumber()}\t{frame.GetMethod().Name}()";
		}

		public static void Warning(string message, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			if (InnerLogger != null)
			{
				InnerLogger.Warning(message, GetFormatStackFrameInfo(traceLevel));
			}
		}

		public static void Warning(string message, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0, params object[] args)
		{
			if (InnerLogger != null)
			{
				InnerLogger.Warning(string.Format(message, args), GetFormatStackFrameInfo(traceLevel));
			}
		}

		public static void Error(string message, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			if (InnerLogger != null)
			{
				InnerLogger.Error(message, GetFormatStackFrameInfo(traceLevel));
			}
		}

		public static void Warning(string message, Exception ex, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			if (InnerLogger != null)
			{
				InnerLogger.Warning(message, ex, GetFormatStackFrameInfo(traceLevel));
			}
		}

		public static void Error(string message, Exception ex, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			if (InnerLogger != null)
			{
				InnerLogger.Error(message, ex, GetFormatStackFrameInfo(traceLevel));
			}
		}

		public static void Write(Exception ex, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			Error("", ex, traceLevel + 1);
		}

		public static void Write(Exception ex, string message, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			Error(message, ex, traceLevel + 1);
		}

		public static void Write(string message, int traceLevel = 2, [CallerFilePath] string file = "", [CallerMemberName] string member = "", [CallerLineNumber] int line = 0)
		{
			Info(message, isTraceOn: false, traceLevel + 1);
		}
	}
}
