using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;

public class GameLogger
{
    // 使用StringBuilder来优化字符串的重复构造
    private static StringBuilder sLogStr = new StringBuilder();
    // 日志文件存储位置
    public static string mLogFileSavePath;

    public static void Init()
    {
        var date = System.DateTime.Now.ToString("yyyyMMddhhmmss");
        mLogFileSavePath = string.Format("{0}/output_{1}.log", Application.persistentDataPath, date);
        // 监听系统日志
        Application.logMessageReceived += OnLogCallBack;
    }

    /// <summary>
    /// 打印日志回调
    /// </summary>
    /// <param name="condition">日志文本</param>
    /// <param name="stackTrace">调用堆栈</param>
    /// <param name="type">日志类型</param>
    public static void OnLogCallBack(string condition, string stackTrace, LogType type)
    {
        sLogStr.Append(condition);
        sLogStr.Append("\n");
        sLogStr.Append(stackTrace);
        sLogStr.Append("\n");

        if (sLogStr.Length <= 0) return;
        if (!File.Exists(mLogFileSavePath))
        {
            // 检查文件是否存在，不存在则创建
            var fs = File.Create(mLogFileSavePath);
            fs.Close();
        }
        using (var sw = File.AppendText(mLogFileSavePath))
        {
            // 记录文件内容
            sw.WriteLine(sLogStr.ToString());
        }
        sLogStr.Remove(0, sLogStr.Length);
    }

    public static void UploadLog(string desc)
    {
        LogUploader.StartUploadLog(mLogFileSavePath, desc);
    }

    public static void Log(object msg, UnityEngine.Object context = null)
    {
        Debug.Log(msg, context);
    }
    public static void LogError(object msg, UnityEngine.Object context = null)
    {
        Debug.LogError(msg, context);
    }
    public static void LogGreen(object msg, UnityEngine.Object context = null)
    {
        Debug.Log(FmtColor("#00ff00", msg), context);
    }

    public static void LogWarning(object msg, UnityEngine.Object context = null)
    {
        Debug.LogWarning(msg, context);
    }

    public static object FmtColor(string color, object msg)
    {
        if (msg is string)
            return FmtColor(color, (string)msg);
        return string.Format("<color={0}>{1}</color>", color, msg);
    }

    /// <summary>
    /// 格式化颜色日志
    /// </summary>
    public static object FmtColor(string color, string msg)
    {
        int p = msg.IndexOf('\n');
        if (p >= 0) p = msg.IndexOf('\n', p + 1);           // 可以同时显示两行
        if (p < 0 || p > msg.Length - 1) return string.Format("<color={0}>{1}</color>", color, msg);
        if (p > 2 && msg[p - 1] == '\r') p--;
        return string.Format("<color={0}>{1}</color>{2}", color, msg.Substring(0, p), msg.Substring(p));
    }

#region 解决日志双击溯源问题
#if UNITY_EDITOR
    [UnityEditor.Callbacks.OnOpenAssetAttribute(0)]
    static bool OnOpenAsset(int instanceId, int line)
    {
        string stackTrace = GetStackTrace();
        if (!string.IsNullOrEmpty(stackTrace) && stackTrace.Contains("GameLogger:Log"))
        {
            // 使用正则表达式匹配at的哪个脚本哪一行
            var matches = System.Text.RegularExpressions.Regex.Match(stackTrace, @"\(at (.+)\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            string pathLine = "";
            while (matches.Success)
            {
                pathLine = matches.Groups[1].Value;
                if (!pathLine.Contains("GameLogger.cs"))
                {
                    int splitIndex = pathLine.LastIndexOf(":");
                    // 脚本路径
                    string path = pathLine.Substring(0, splitIndex);
                    // 行号
                    line = System.Convert.ToInt32(pathLine.Substring(splitIndex + 1));
                    string fullPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets"));
                    fullPath = fullPath + path;
                    // 跳转到目标代码的特定行
                    UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(fullPath.Replace('/', '\\'), line);
                    break;
                }
                matches = matches.NextMatch();
            }
            return true;
        }
        return false;
    }

    /// <summary>
    /// 获取当前日志窗口选中的日志的堆栈信息
    /// </summary>
    /// <returns></returns>
    static string GetStackTrace()
    {
        // 通过反射获取ConsoleWindow类
        var ConsoleWindowType = typeof(UnityEditor.EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");
        // 获取窗口实例
        var fieldInfo = ConsoleWindowType.GetField("ms_ConsoleWindow", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
        var consoleInstance = fieldInfo.GetValue(null);
        if (consoleInstance != null)
        {
            if ((object)UnityEditor.EditorWindow.focusedWindow == consoleInstance)
            {
                // 获取_ActiveText成员
                fieldInfo = ConsoleWindowType.GetField("m_ActiveText", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                // 获取_ActiveText值
                string activeText = fieldInfo.GetValue(consoleInstance).ToString();
                return activeText;
            }
        }
        return null;
    }
#endif
#endregion 解决日志双击溯源问题
}