from __future__ import annotations

import shutil
import subprocess
import tempfile
import time
from pathlib import Path
from typing import Iterable


def terminate_process(process: subprocess.Popen, *, timeout: float = 1.5) -> None:
    """尽量温和地结束子进程，避免打包临时目录被子进程占用。"""
    try:
        if process.poll() is not None:
            return
        process.terminate()
        process.wait(timeout=timeout)
    except Exception:
        try:
            if process.poll() is None:
                process.kill()
        except Exception:
            pass


def terminate_processes(processes: Iterable[subprocess.Popen], *, timeout: float = 1.5) -> None:
    """批量结束仍在运行的子进程。"""
    for process in list(processes):
        terminate_process(process, timeout=timeout)


def close_channel(channel) -> None:
    """关闭 Paramiko 通道，防止 SSH 会话在退出时继续占用资源。"""
    if channel is None:
        return
    try:
        channel.close()
    except Exception:
        pass


def cleanup_stale_pyinstaller_dirs(*, max_age_hours: float = 12) -> None:
    """启动时清理陈旧 _MEI 目录；只处理系统临时目录下的 PyInstaller 残留。"""
    temp_root = Path(tempfile.gettempdir()).resolve()
    expire_before = time.time() - max(1.0, max_age_hours) * 60 * 60
    for path in temp_root.glob("_MEI*"):
        try:
            resolved = path.resolve()
        except OSError:
            continue
        if not str(resolved).lower().startswith(str(temp_root).lower()):
            continue
        try:
            stat = resolved.stat()
        except OSError:
            continue
        if stat.st_mtime > expire_before:
            continue
        try:
            if resolved.is_dir():
                shutil.rmtree(resolved, ignore_errors=True)
            elif resolved.is_file():
                resolved.unlink(missing_ok=True)
        except OSError:
            pass
