using Ayay.SerilogLogs;
using Serilog;
using System.Diagnostics;
using System.Timers;

namespace SHH.MjpegPlayer;

/// <summary>
/// 内存监控
/// </summary>
public static class MemoryWatchdog
{
    private static readonly ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);

    private static System.Timers.Timer? _timer;
    private static long _thresholdBytes;

    private static ILogger _logger => Log.Logger;

    /// <summary>
    /// 启动内存监控
    /// </summary>
    /// <param name="intervalSeconds">检查间隔(秒)，默认60秒</param>
    /// <param name="limitMB">内存阈值(MB)，超过此值自动退出，默认800MB</param>
    public static void Start(int intervalSeconds = 60, int limitMB = 800)
    {
        // 1. 参数安全检查
        if (intervalSeconds < 1) intervalSeconds = 1; // 至少 1 秒
        if (limitMB < 100) limitMB = 100; // 至少100MB，防止误杀

        // 2. 转换单位
        // MB -> Bytes
        _thresholdBytes = (long)limitMB * 1024 * 1024;

        // 秒 -> 毫秒
        double intervalMs = intervalSeconds * 1000.0;

        // 3. 初始化定时器
        Stop(); // 防止重复启动
        _timer = new System.Timers.Timer(intervalMs);
        _timer.Elapsed += CheckMemoryUsage;
        _timer.AutoReset = true; // 循环执行
        _timer.Start();

        // 可选：记录启动日志
        if (_logger != null)
        {
            _sysLog.Warning($"[系统] 内存看门狗已启动。每 {intervalSeconds} 秒检查一次，阈值: {limitMB} MB.");
        }
    }

    private static void CheckMemoryUsage(object sender, ElapsedEventArgs e)
    {
        try
        {
            Process currentProc = Process.GetCurrentProcess();

            // 【重要】刷新快照
            currentProc.Refresh();

            long currentUsage = currentProc.WorkingSet64;

            if (currentUsage > _thresholdBytes)
            {
                double currentMB = currentUsage / 1024.0 / 1024.0;
                double limitMB = _thresholdBytes / 1024.0 / 1024.0;

                if (_logger != null)
                {
                    _sysLog.Warning($"[严重] 内存占用 ({currentMB:F2} MB) 超过阈值 ({limitMB} MB)，程序即将自杀重启或退出.");
                }

                // 等待日志输出
                for (var i = 0; i < 10; i++)
                {
                    System.Threading.Thread.Sleep(100);
                }

                // 强制退出
                Environment.Exit(0);
            }
        }
        catch (Exception ex)
        {
            if (_logger != null)
            {
                _sysLog.Warning($"[严重] 内存检查出错.");
            }
        }
    }

    public static void Stop()
    {
        if (_timer != null)
        {
            _timer.Stop();
            _timer.Dispose();
            _timer = null;
        }
    }
}