# -*- coding: utf-8 -*-
"""Erlang and build-tool command resolution."""

from .shared import *

def get_erl_cmd(erl_path: str = None) -> str:
    """根据配置路径获取 erl 可执行文件路径
    
    Args:
        erl_path: Erlang 安装根目录（如 E:/app/erlang/Erlang_OTP_25）
    
    Returns:
        erl 可执行文件的完整路径，或默认的 'erl'
    """
    if erl_path and erl_path.strip():
        if IS_WINDOWS:
            erl_exe = Path(erl_path.strip()) / 'bin' / 'erl.exe'
            if erl_exe.exists():
                return str(erl_exe)
        else:
            erl_bin = Path(erl_path.strip()) / 'bin' / 'erl'
            if erl_bin.exists():
                return str(erl_bin)
    return 'erl'


def subprocess_args_to_display(args: List[str]) -> str:
    """将 subprocess 参数列表转为可读的命令字符串（仅用于显示/日志）"""
    parts = []
    for a in args:
        if ' ' in a or '"' in a or "'" in a or any(c in a for c in '()[]{}&|<>^'):
            parts.append(f'"{a}"')
        else:
            parts.append(a)
    return ' '.join(parts)


def get_escript_cmd(erl_path: str = None) -> str:
    """根据配置路径获取 escript 可执行文件路径
    
    Args:
        erl_path: Erlang 安装根目录
    
    Returns:
        escript 可执行文件的完整路径，或默认的 'escript'
    """
    if erl_path and erl_path.strip():
        if IS_WINDOWS:
            escript_exe = Path(erl_path.strip()) / 'bin' / 'escript.exe'
            if escript_exe.exists():
                return str(escript_exe)
        else:
            escript_bin = Path(erl_path.strip()) / 'bin' / 'escript'
            if escript_bin.exists():
                return str(escript_bin)
    return 'escript'


def _ensure_epmd_daemon(erl_path: Optional[str] = None) -> None:
    """尽量执行 epmd -daemon。本机已有 epmd 时通常无害（就绪则不再重复监听）。"""
    erl_exe = Path(get_erl_cmd(erl_path))
    epmd = erl_exe.parent / ("epmd.exe" if IS_WINDOWS else "epmd")
    if not epmd.is_file():
        which = shutil.which("epmd")
        if not which:
            return
        epmd = Path(which)
    try:
        subprocess.run(
            [str(epmd), "-daemon"],
            capture_output=True,
            timeout=5,
            creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0) if IS_WINDOWS else 0,
        )
    except Exception:
        pass


def get_rebar3_cmd(server_root: str, erl_path: str = None) -> str:
    """获取 rebar3 执行命令
    
    如果配置了 erl_path，直接用配置路径的 escript 来运行 rebar3 脚本，
    而不是依赖系统 PATH 中的 escript。
    
    Args:
        server_root: 服务器根目录（rebar3 脚本所在目录）
        erl_path: Erlang 安装根目录
    
    Returns:
        rebar3 执行命令字符串
    """
    escript = get_escript_cmd(erl_path)
    if IS_WINDOWS:
        rebar3_script = Path(server_root) / 'rebar3'
        if escript != 'escript':
            return f'"{escript}" "{rebar3_script}"'
        return REBAR3_CMD
    else:
        rebar3_script = Path(server_root) / 'rebar3'
        if escript != 'escript':
            return f'"{escript}" "{rebar3_script}"'
        return './rebar3'


def get_local_ip() -> str:
    """获取本机IP地址"""
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except:
        return "127.0.0.1"


def get_ebin_paths(server_root: str, profile: str = 'game_server_dev') -> List[str]:
    """获取所有 ebin 目录路径
    
    Args:
        server_root: 服务器根目录
        profile: rebar3 profile 名称 (game_server_dev/login_server_dev/client_server_dev)
    
    Returns:
        ebin 目录路径列表
    """
    ebin_paths = []
    build_dir = Path(server_root) / "_build" / profile / "lib"
    
    if build_dir.exists():
        for app_dir in build_dir.iterdir():
            if app_dir.is_dir():
                ebin_dir = app_dir / "ebin"
                if ebin_dir.exists():
                    ebin_paths.append(str(ebin_dir))
    
    # 添加 checkouts 目录
    checkouts_dir = Path(server_root) / "_build" / profile / "checkouts"
    if checkouts_dir.exists():
        for app_dir in checkouts_dir.iterdir():
            if app_dir.is_dir():
                ebin_dir = app_dir / "ebin"
                if ebin_dir.exists():
                    ebin_paths.append(str(ebin_dir))
    
    return ebin_paths
