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

namespace SHH.MjpegPlayer
{
    /// <summary>
    /// 进程扩展
    /// </summary>
    public static class ProcessExtension
    {
        private static ILogger _sysLog = Log.ForContext("SourceContext", LogModules.Core);

        #region GetProcessName

        /// <summary>
        /// 获取进程名称
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        public static string GetProcessName(this int pid)
        {
            try
            {
                var process = Process.GetProcessById(pid);
                return process.ProcessName;
            }
            catch (Exception ex)
            {
                _sysLog.Error(ex, "查询进程名出错, Pid: {Pid}", pid);
                return string.Empty;
            }
        }

        #endregion

        #region KillProcessByPid

        /// <summary>
        /// 杀掉进程
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="procName"></param>
        /// <returns></returns>
        public static bool KillProcessByPid(this int pid, string procName = "")
        {
            try
            {
                var process = Process.GetProcessById(pid);
                if (process != null)
                {
                    procName = process.ProcessName;
                    process.Kill();

                    _sysLog.Information("成功通过 PID 杀掉进程 - Pid: {Pid}, Name: {Name}", pid, procName);
                    return true;
                }

                _sysLog.Warning("无法获取进程实例 - Pid: {Pid}", pid);
                return false;
            }
            catch (ArgumentException)
            {
                _sysLog.Warning("杀掉进程失败，Pid: {Pid} 不存在或已提前退出", pid);
                return false;
            }
            catch (Exception ex)
            {
                _sysLog.Error(ex, "杀掉进程异常, Pid: {Pid}, 进程名: {Name}", pid, procName);
                return false;
            }
        }

        #endregion

        #region KillProcessByName

        /// <summary>
        /// 杀掉进程
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="procName"></param>
        /// <returns></returns>
        public static int KillProcessByName(this string procName)
        {
            if (string.IsNullOrWhiteSpace(procName)) return 0;

            int killCount = 0;
            try
            {
                var processes = Process.GetProcessesByName(procName);
                foreach (var proc in processes)
                {
                    using (proc) // Optimized: 确保 Process 资源被释放
                    {
                        try
                        {
                            if (proc.IsHighPrivilegeProcess()) continue;

                            int currentId = proc.Id;
                            proc.Kill();
                            killCount++;
                            _sysLog.Information("成功通过名称杀掉进程 - Pid: {Pid}, Name: {Name}", currentId, procName);
                        }
                        catch (Exception ex)
                        {
                            _sysLog.Error(ex, "通过名称杀掉单个进程失败: {Name}", procName);
                        }
                    }
                }
                return killCount;
            }
            catch (Exception ex)
            {
                _sysLog.Error(ex, "通过名称杀掉进程列表异常: {Name}", procName);
                return 0;
            }
        }

        #endregion

        #region StartProcess

        /// <summary>
        /// 开启进程
        /// </summary>
        /// <param name="procPath"></param>
        public static bool StartProcess(this string procPath)
        {
            try
            {
                if (!File.Exists(procPath))
                {
                    _sysLog.Error("启动进程失败，路径不存在: {Path}", procPath);
                    return false;
                }

                // Optimized: 显式记录启动行为
                var process = Process.Start(procPath);
                if (process != null)
                {
                    _sysLog.Information("进程启动成功: {Path}, Pid: {Pid}", procPath, process.Id);
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                _sysLog.Error(ex, "启动进程异常: {Path}", procPath);
                return false;
            }
        }

        #endregion

        #region IsHighPrivilegeProcess

        /// <summary>
        /// 检测是否高权限等级
        /// </summary>
        /// <param name="proc"></param>
        /// <returns></returns>
        public static bool IsHighPrivilegeProcess(this Process proc)
        {
            // 典型的高权限进程列表（可根据实际需求扩展）
            string[] highPrivilegeProcesses = new[] {
                "System", "smss.exe", "csrss.exe", "wininit.exe", "services.exe",
                "lsass.exe", "winlogon.exe", "spoolsv.exe", "svchost.exe",
                "csrss", "msedge"
            };

            // 检查进程名称是否在高权限列表中
            foreach (string name in highPrivilegeProcesses)
            {
                if (proc.ProcessName.Equals(name, StringComparison.OrdinalIgnoreCase))
                    return true;
            }

            // 检查进程是否属于系统会话（Session 0）
            try
            {
                return proc.SessionId == 0;
            }
            catch
            {
                // 如果无法获取 SessionId，保守返回 true
                return true;
            }
        }

        #endregion
    }
}