using System;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using UnityEngine;

[XLua.LuaCallCSharp]
public class AppMonitor 
{
    static AppMonitor _instance = null;
    public static AppMonitor Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new();
            }
            return _instance;
        }
    }
    public string address = "ws://10.2.40.166:28017";
    public string wsName = "monitor";
    public string launchSession;
    public string channelName;
    readonly string launchSessionLogPath;
    readonly string launchSessionPerfPath;
    readonly string launchSessionMemPath;
    Item logItem;
    Item perfItem;
    Item memItem;
    Timer timer;
    AppMonitor()
    {
        launchSession = $"{Application.productName}/{Application.platform}/{SystemInfo.deviceUniqueIdentifier}/{DateTime.Now.ToString("HH_mm_ss")}";
        launchSessionLogPath = $"{launchSession}.log.txt";
        launchSessionPerfPath = $"{launchSession}.perf.txt";
        launchSessionMemPath = $"{launchSession}.mem.txt";
        channelName = $"{Application.productName}_{SystemInfo.deviceUniqueIdentifier}";
        logItem = new Item() { 
            cmd = "log",
            path = launchSessionLogPath,
            appendLF = true,
            appendCR = true,
            appendDate = true,
            channel = channelName,
        };
        perfItem = new Item() { 
            cmd = "perf",
            path = launchSessionPerfPath,
            appendLF = true,
            appendCR = true,
            appendDate = true,
            channel = channelName,
        };
        memItem = new Item() { 
            cmd = "mem",
            path = launchSessionMemPath,
            appendLF = true,
            appendCR = true,
            appendDate = true,
            channel = channelName,
        };

        timer = new Timer
        {
            Interval = 5000,
            AutoReset = true 
        };
        string heartbeat = $"{{\"channel\":\"{this.channelName}\",\"cmd\":\"heartbeat\",\"data\":\"\"}}";
        timer.Elapsed += (sender,e)=> { 
            WebsocketMgr.Instance.Send(wsName,heartbeat);
        };
        timer.Start();

    }
    public void Connect() {
        if (Application.isEditor) return;
        Application.logMessageReceivedThreaded += (string condition, string stackTrace, LogType type) =>
        {
            this.SendLog(condition);
        };
        WebsocketMgr.Instance.Connect(wsName, address, (ev,msg) => {
            if (ev == "open") { 
                WebsocketMgr.Instance.Send(wsName,$"{{\"channel\" : \"{this.channelName}\"}}");
            }
        });
    }
    struct Item {
        public string cmd;
        public string data;
        public string path;
        public bool appendLF;
        public bool appendCR;
        public bool appendDate;
        public string channel;
    }
    public void SendLog(string data)
    {
        logItem.data = data;
        WebsocketMgr.Instance.Send(wsName,JsonUtility.ToJson(logItem));
    }
    public void SendPerf(string data)
    {
        perfItem.data = data;
        WebsocketMgr.Instance.Send(wsName,JsonUtility.ToJson(perfItem));
    }
    public void SendMem(string data)
    {
        memItem.data = data;
        WebsocketMgr.Instance.Send(wsName,JsonUtility.ToJson(memItem));
    }
}
