# -*- coding: utf-8 -*-
"""Tracking and closing windows launched by the manager."""

from .shared import *

_launched_windows: Dict[str, List[Dict[str, Any]]] = {}
_launched_windows_lock = threading.Lock()


def _normalize_server_key(server_name: str) -> str:
    """返回不含 @ip 的服务器基础名称。"""
    if not server_name:
        return ''
    return server_name.split('@', 1)[0]


def register_launched_window(server_name: str, kind: str, window_title: str,
                             launch_info: str = '') -> None:
    """注册通过本工具启动的窗口。
    
    Args:
        server_name: 关联的服务器名（如 xxx_game_s1 或 xxx_game_s1@1.2.3.4）
        kind: 'server'（服务进程窗口）或 'remsh'（远程连接窗口）
        window_title: 窗口标题（Windows 下用 taskkill 依据此标题关闭）
        launch_info: 启动方式信息，Linux 下形如 'screen:xxx' / 'tmux:xxx'
    """
    key = _normalize_server_key(server_name)
    if not key:
        return
    entry = {
        'kind': kind,
        'title': window_title,
        'launch_info': launch_info or '',
    }
    with _launched_windows_lock:
        _launched_windows.setdefault(key, []).append(entry)


def get_launched_windows(server_name: str) -> List[Dict[str, Any]]:
    """获取与该服务器关联的所有已记录窗口条目。"""
    key = _normalize_server_key(server_name)
    with _launched_windows_lock:
        return list(_launched_windows.get(key, []))


def _close_by_title_windows(title: str) -> Tuple[bool, str]:
    """Windows 下按窗口标题强制关闭匹配的 cmd.exe。
    
    考虑 cmd.exe 以管理员运行时系统会自动给标题加上"管理员:"/"Administrator:"前缀，
    我们按几种可能的前缀逐个尝试匹配。
    """
    candidates = [
        title,
        f'管理员: {title}',
        f'管理员：{title}',
        f'Administrator: {title}',
    ]
    last_msg = ''
    for t in candidates:
        try:
            result = subprocess.run(
                ['taskkill', '/F', '/T', '/FI', f'WINDOWTITLE eq {t}*'],
                capture_output=True, text=True, timeout=5
            )
        except Exception as e:
            last_msg = f'关闭窗口异常: {e}'
            continue
        stdout = (result.stdout or '').strip()
        # returncode=0 且 stdout 里含 "SUCCESS"/"成功" 表明确实杀到了进程
        if result.returncode == 0 and stdout:
            low = stdout.lower()
            if 'success' in low or '成功' in stdout:
                return (True, f'已关闭窗口: {t}')
        last_msg = f'未匹配到窗口标题: {t}'
    # 全部尝试完仍未命中（可能用户已手动关闭），也当作成功但给出提示
    return (True, f'未找到匹配窗口（可能已关闭）: {title}')


def _close_single_window(entry: Dict[str, Any]) -> Tuple[bool, str]:
    """关闭单个窗口条目。"""
    title = entry.get('title', '') or ''
    launch_info = entry.get('launch_info', '') or ''
    
    if IS_WINDOWS:
        # 优先按 PID 精确关闭（不受管理员标题前缀影响，且能通过 /T 杀掉整个进程树）
        if launch_info.startswith('winpid:') or launch_info.startswith('wtpid:'):
            try:
                pid_str = launch_info.split(':', 1)[1]
                pid = int(pid_str)
                result = subprocess.run(
                    ['taskkill', '/F', '/T', '/PID', str(pid)],
                    capture_output=True, text=True, timeout=5
                )
                if result.returncode == 0:
                    return (True, f'已关闭窗口 (PID={pid}): {title}')
                # 128: 未找到进程（可能已退出），视为成功
                return (True, f'进程已不存在 (PID={pid}): {title}')
            except Exception as e:
                # 回退到标题匹配
                logger_msg = f'按 PID 关闭失败: {e}，尝试按标题匹配'
                ok, msg = _close_by_title_windows(title)
                return (ok, f'{logger_msg}；{msg}')

        if launch_info.startswith('wttab:'):
            return (True, f'Windows Terminal 页签已启动但未取得 PID，跳过自动关闭: {title}')
        
        # 兜底：按窗口标题匹配（可能被"管理员:"等前缀影响）
        if not title:
            return (False, '无窗口标题，无法关闭')
        return _close_by_title_windows(title)
    else:
        try:
            if launch_info.startswith('screen:'):
                session = launch_info.split(':', 1)[1]
                subprocess.run(['screen', '-X', '-S', session, 'quit'],
                               capture_output=True, timeout=5)
                return (True, f'已关闭 screen 会话: {session}')
            if launch_info.startswith('tmux:'):
                session = launch_info.split(':', 1)[1]
                subprocess.run(['tmux', 'kill-session', '-t', session],
                               capture_output=True, timeout=5)
                return (True, f'已关闭 tmux 会话: {session}')
            if launch_info.startswith('background:'):
                return (True, '后台进程无独立控制台，跳过')
            return (False, f'未知启动方式: {launch_info}')
        except Exception as e:
            return (False, f'关闭会话异常: {e}')


def close_launched_windows(server_name: str) -> List[Tuple[Dict[str, Any], bool, str]]:
    """关闭与该服务器关联的所有已记录窗口（一次性取出并清空记录）。
    
    Returns:
        列表，每项为 (entry, is_success, message)
    """
    key = _normalize_server_key(server_name)
    with _launched_windows_lock:
        entries = _launched_windows.pop(key, [])
    results: List[Tuple[Dict[str, Any], bool, str]] = []
    for entry in entries:
        ok, msg = _close_single_window(entry)
        results.append((entry, ok, msg))
    return results
