"""
WorkerNode 业务逻辑服务层（Service）

负责 Worker 节点相关的业务逻辑处理
"""

import logging
from typing import Any

from apps.engine.repositories import DjangoWorkerRepository

logger = logging.getLogger(__name__)


class WorkerService:
    """Worker 节点业务逻辑服务"""

    def __init__(self) -> None:
        """初始化服务，注入 Repository 依赖"""
        self.repo = DjangoWorkerRepository()

    # ==================== 查询 ====================

    def get_worker(self, worker_id: int):
        """根据 ID 获取 Worker 节点"""
        return self.repo.get_by_id(worker_id)

    def get_all_workers(self):
        """获取所有 Worker 节点查询集"""
        return self.repo.get_all()

    # ==================== 状态更新 ====================

    def update_status(self, worker_id: int, status: str) -> bool:
        """更新 Worker 节点状态
        
        Args:
            worker_id: Worker ID
            status: 状态 (pending/deploying/online/offline)
        """
        return self.repo.update_status(worker_id, status)


    def delete_worker(self, worker_id: int) -> bool:
        """删除 Worker 节点"""
        return self.repo.delete_by_id(worker_id)

    # ==================== 自注册 ====================

    def register_worker(self, name: str, is_local: bool = True):
        """
        注册 Worker 节点（本地 Worker 自注册用）
        
        幂等操作：已存在则返回现有节点。
        
        Args:
            name: Worker 名称
            is_local: 是否为本地节点
            
        Returns:
            (WorkerNode, created) 元组
        """
        return self.repo.get_or_create_by_name(
            name=name,
            is_local=is_local
        )

    def remote_uninstall(
        self, 
        worker_id: int,
        ip_address: str, 
        ssh_port: int, 
        username: str, 
        password: str | None
    ) -> tuple[bool, str]:
        """
        在远程主机上执行卸载脚本
        
        Args:
            worker_id: Worker ID（仅用于日志）
            ip_address: SSH 主机地址
            ssh_port: SSH 端口
            username: SSH 用户名
            password: SSH 密码
            
        Returns:
            (success, message) 元组
        """
        if not password:
            return False, "未配置 SSH 密码，跳过远程卸载"
        
        try:
            import paramiko
            from apps.engine.services.deploy_service import get_uninstall_script
            
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            
            logger.info(f"[卸载] 正在连接 {ip_address}...")
            ssh.connect(
                ip_address,
                port=ssh_port,
                username=username,
                password=password,
                timeout=30
            )
            
            # 上传卸载脚本
            uninstall_script = get_uninstall_script()
            remote_script_path = '/tmp/xingrin_uninstall.sh'
            
            sftp = ssh.open_sftp()
            with sftp.file(remote_script_path, 'w') as f:
                f.write(uninstall_script)
            sftp.chmod(remote_script_path, 0o755)
            sftp.close()
            
            # 执行卸载脚本
            logger.info(f"[卸载] 正在执行卸载脚本...")
            stdin, stdout, stderr = ssh.exec_command(f"bash {remote_script_path}")
            exit_status = stdout.channel.recv_exit_status()
            
            ssh.close()
            
            if exit_status == 0:
                logger.info(f"[卸载] Worker {worker_id} 远程卸载成功")
                return True, "远程卸载成功"
            else:
                error = stderr.read().decode().strip()
                logger.warning(f"[卸载] Worker {worker_id} 远程卸载失败: {error}")
                return False, f"远程卸载失败: {error}"
                
        except Exception as e:
            logger.warning(f"[卸载] Worker {worker_id} 远程卸载异常: {e}")
            return False, f"远程卸载异常: {str(e)}"

    def execute_remote_command(
        self,
        ip_address: str,
        ssh_port: int,
        username: str,
        password: str | None,
        command: str
    ) -> tuple[bool, str]:
        """
        在远程主机上执行命令
        
        Args:
            ip_address: SSH 主机地址
            ssh_port: SSH 端口
            username: SSH 用户名
            password: SSH 密码
            command: 要执行的命令
            
        Returns:
            (success, message) 元组
        """
        if not password:
            return False, "未配置 SSH 密码"
        
        try:
            import paramiko
            
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            
            ssh.connect(
                ip_address,
                port=ssh_port,
                username=username,
                password=password,
                timeout=30
            )
            
            stdin, stdout, stderr = ssh.exec_command(command, timeout=120)
            exit_status = stdout.channel.recv_exit_status()
            
            ssh.close()
            
            if exit_status == 0:
                return True, stdout.read().decode().strip()
            else:
                error = stderr.read().decode().strip()
                return False, error
                
        except Exception as e:
            return False, str(e)


__all__ = ["WorkerService"]
