# coding: utf-8
import os, sys, json, time
from common import *
import subprocess,psutil,platform


"""
获取服务状态
@name  服务名称
return （-1：未安装 0：未启动 1：已启动）
"""
def get_server_status(name):
    """
    获取服务状态（跨平台支持）
    @name 服务名称
    @return （-1：未安装 0：未启动 1：已启动）
    """
    system = platform.system().lower()

    if system == "windows":
        try:
            service = psutil.win_service_get(name)
            return 1 if service.status() == "running" else 0
        except Exception:
            return -1
    elif system in ["linux", "darwin"]:
        try:
            result = subprocess.run(
                ["systemctl", "is-active", name],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )
            return 1 if result.returncode == 0 and result.stdout.strip() == "active" else 0
        except Exception:
            return -1
    return -1

"""
创建系统服务（跨平台支持）
@name 服务名称
@disName 显示名称
@path exe文件路径
@args 服务参数
@description 服务描述
@userName 启动用户（仅 Windows 支持）
@password 用户密码（仅 Windows 支持）
@return (状态, 错误信息)
"""
def create_server(name, disName, path, args=None, description=None, userName=None, password=None):
    """
    创建系统服务（跨平台支持）
    """
    system = platform.system().lower()

    if system == "windows":
        try:
            import win32service
            import win32serviceutil as service
            
            if userName and userName.find('.\\') < 0:
                userName = '.\\{}'.format(userName)

            path = to_path(path)
            service.InstallService(name, name, disName, win32service.SERVICE_AUTO_START, errorControl=None,
                                bRunInteractive=0, serviceDeps=None, userName=userName, password=password, exeName=path,
                                perfMonIni=None, perfMonDll=None, exeArgs=args, description=description,
                                delayedstart=None)
            if get_server_status(name) > -1:
                set_server_status(name, 'start')
                return True, ''
            else:
                return False, ''
        except:
            return False, get_error_info()

    elif system in ["linux", "darwin"]:
        try:
            service_content = f"""
[Unit]
Description={description or disName}
After=network.target

[Service]
ExecStart={path} {args or ""}
Restart=always
User={userName or "root"}

[Install]
WantedBy=multi-user.target
"""
            service_file = f"/etc/systemd/system/{name}.service"
            with open(service_file, "w") as f:
                f.write(service_content)
            subprocess.run(["systemctl", "daemon-reload"], check=True)
            subprocess.run(["systemctl", "enable", name], check=True)
            subprocess.run(["systemctl", "start", name], check=True)
            return True, f"服务【{name}】已成功创建并启动"
        except Exception as e:
            return False, f"Linux/macOS 服务创建失败: {str(e)}"
    return False, "不支持的操作系统"


def start_service(name):
    """
    启动服务（跨平台支持）
    """
    system = platform.system().lower()

    if system == "windows":
        try:
            import win32serviceutil
            win32serviceutil.StartService(name)
            return True, f"服务【{name}】已成功启动"
        except Exception as e:
            return False, f"Windows 服务启动失败: {str(e)}"
    elif system in ["linux", "darwin"]:
        try:
            subprocess.run(["systemctl", "start", name], check=True)
            subprocess.run(["/etc/init.d/{}".format(name), "start"], check=True)
            return True, f"服务【{name}】已成功启动"
        except Exception as e:
            return False, f"Linux/macOS 服务启动失败: {str(e)}"
    return False, "不支持的操作系统"

def stop_service(name):
    """
    停止服务（跨平台支持）
    """
    system = platform.system().lower()

    if system == "windows":
        try:
            import win32serviceutil
            win32serviceutil.StopService(name)
            return True, f"服务【{name}】已成功停止"
        except Exception as e:
            return False, f"Windows 服务停止失败: {str(e)}"
    elif system in ["linux", "darwin"]:
        try:
            subprocess.run(["systemctl", "stop", name], check=True)
            #/etc/init.d/{name} stop
            subprocess.run(["/etc/init.d/{}".format(name), "stop"], check=True)
            return True, f"服务【{name}】已成功停止"
        except Exception as e:
            return False, f"Linux/macOS 服务停止失败: {str(e)}"
    return False, "不支持的操作系统"

def set_server_status(name, status):
    """
    设置服务状态
    @name 服务名称
    @status 服务状态（start）
    return array(状态，详情)
    """
    old_status = get_server_status(name)
    if old_status > -1:
        try:
            if status == 'reload' or status == 'restart':
                ret, error = stop_service(name)
                if not ret: ret, error

                ret, error = start_service(name)
                if not ret: return ret, error

                return True, ''
            else:
                if status == 'stop':
                    ret, error = stop_service(name)
                    if not ret: ret, error
                else:
                    ret, error = start_service(name)
                    if not ret: return ret, error
            return True, ''
        except:
            return False, get_error_info()
    return False, "{}服务未安装.".format(name)

def delete_server(name):
    """
    删除系统服务（跨平台支持）
    """
    system = platform.system().lower()

    if system == "windows":
        try:
            import win32serviceutil
            stop_service(name)
            win32serviceutil.RemoveService(name)
            return True, f"服务【{name}】已成功删除"
        except Exception as e:
            return False, f"Windows 服务删除失败: {str(e)}"
    elif system in ["linux", "darwin"]:
        try:
            stop_service(name)
            service_file = f"/etc/systemd/system/{name}.service"
            subprocess.run(["systemctl", "disable", name], check=True)
            subprocess.run(["rm", "-f", service_file], check=True)
            subprocess.run(["systemctl", "daemon-reload"], check=True)

            #/init.d/{name} stop
            subprocess.run(["/etc/init.d/{}".format(name), "stop"], check=True)
            subprocess.run(["/etc/init.d/{}".format(name), "remove"], check=True)            
            return True, f"服务【{name}】已成功删除"
        except Exception as e:
            return False, f"Linux/macOS 服务删除失败: {str(e)}"
    return False, "不支持的操作系统"



def change_server_start_type(name, type):
    """
    修改服务启动类型（跨平台支持，支持 systemd 和 init.d）
    @name 服务名称
    @type 启动类型（1：自动 0：手动 -1：禁用）
    @return (状态, 错误详情)
    """
    system = platform.system().lower()

    if system == "windows":
        # Windows 平台
        try:
            import win32service
            import win32serviceutil

            # 映射启动类型
            if type == -1:
                start_type = win32service.SERVICE_DISABLED
            elif type == 1:
                start_type = win32service.SERVICE_AUTO_START
            else:
                start_type = win32service.SERVICE_DEMAND_START

            # 修改服务启动类型
            scm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS)
            if scm:
                svc = win32service.OpenService(scm, name, win32service.SERVICE_CHANGE_CONFIG)
                if svc:
                    win32service.ChangeServiceConfig(
                        svc,
                        win32service.SERVICE_NO_CHANGE,
                        start_type,
                        win32service.SERVICE_NO_CHANGE,
                        None,
                        None,
                        0,
                        None,
                        None,
                        None,
                        None
                    )
                    return True, f"服务【{name}】启动类型已成功修改"
            return False, "无法打开服务管理器或服务"
        except Exception as e:
            return False, f"Windows 服务启动类型修改失败: {str(e)}"

    elif system in ["linux", "darwin"]:
        # Linux 和 macOS 平台
        try:
            if os.path.exists(f"/etc/init.d/{name}"):
                # init.d 服务
                init_script = f"/etc/init.d/{name}"
                if type == -1:
                    # 禁用服务（移除启动链接）
                    subprocess.run(["update-rc.d", name, "disable"], check=True)
                    return True, f"init.d 服务【{name}】已禁用"
                elif type == 1:
                    # 启用服务（添加启动链接）
                    subprocess.run(["update-rc.d", name, "defaults"], check=True)
                    return True, f"init.d 服务【{name}】已设置为自动启动"
                else:
                    return False, "init.d 服务不支持手动启动类型"
            else:
                # systemd 服务
                if type == -1:
                    command = ["systemctl", "disable", name]
                elif type == 1:
                    command = ["systemctl", "enable", name]
                else:
                    return False, "systemd 服务不支持手动启动类型"

                # 执行命令修改启动类型
                result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
                if result.returncode == 0:
                    return True, f"服务【{name}】启动类型已成功修改"
                else:
                    return False, f"Linux/macOS 服务启动类型修改失败: {result.stderr.strip()}"
        except Exception as e:
            return False, f"Linux/macOS 服务启动类型修改失败: {str(e)}"

    else:
        # 不支持的系统
        return False, "不支持的操作系统"

def query_server_config(name):
    """
    查询服务配置
    @name 服务名称
    """
    import win32service
    import win32serviceutil
    status = get_server_status(name)
    if status > -1:
        scm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS)
        if scm:
            svc = win32service.OpenService(scm, name, win32service.SC_MANAGER_ALL_ACCESS)
            if svc:
                config = win32service.QueryServiceConfig(svc)
                return config
    return None


"""
获取服务路径（跨平台支持，支持 systemd 和 init.d）
@name 服务名称
@return 服务路径或错误信息
"""
def get_server_path(name):

    system = platform.system().lower()
    if system == "windows":
        try:
            data = psutil.win_service_get(name).as_dict()
            path = data['binpath'].split(' ')[0].replace('"', '')
            return path
        except Exception as e:
            return f"Windows 服务路径获取失败: {str(e)}"
    elif system in ["linux", "darwin"]:
        try:      
            result = subprocess.run(
                ["systemctl", "show", name, "--property=ExecStart"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )
            if result.returncode == 0:
                output = result.stdout.strip()
                if output.startswith("ExecStart="):
                    path = output.split('=', 1)[1].split(' ')[0]
                    return path
      
            init_script = f"/etc/init.d/{name}"
            if os.path.exists(init_script):
                with open(init_script, "r") as f:
                    for line in f:
                        if "exec" in line and not line.strip().startswith("#"):
                            path = line.split("exec", 1)[1].strip().split(' ')[0]
                            return path
                return f"无法解析 init.d 服务【{name}】的路径"

            return f"无法解析服务【{name}】的路径"
        except Exception as e:
            return f"Linux/macOS 服务路径获取失败: {str(e)}"

    else:
        # 不支持的系统
        return "不支持的操作系统"