"""Build standalone Web Sentinel executables with PyInstaller."""
from __future__ import annotations

import os
import subprocess
import sys
from pathlib import Path
from typing import Iterable, List, Sequence

REPO_ROOT = Path(__file__).resolve().parents[2]
DATA_BUNDLES: Sequence[tuple[Path, str]] = (
    (REPO_ROOT / "web_sentinel" / "localization", "web_sentinel/localization"),
    (REPO_ROOT / "web_sentinel" / "gui" / "assets", "web_sentinel/gui/assets"),
    (REPO_ROOT / "web_sentinel" / "gui" / "templates", "web_sentinel/gui/templates"),
    (REPO_ROOT / "web_sentinel" / "gui" / "themes_gui", "web_sentinel/gui/themes_gui"),
)
DATA_SEPARATOR = ";" if os.name == "nt" else ":"


def _extend_with_data(args: List[str]) -> None:
    """Append --add-data entries for resource bundles that exist."""
    for source, destination in DATA_BUNDLES:
        if not source.exists():
            print(f"[WARN] Resource bundle missing, skipped: {source}")
            continue
        bundle = f"{source}{DATA_SEPARATOR}{destination}"
        args.extend(["--add-data", bundle])


def _run_pyinstaller(py_args: Iterable[str]) -> subprocess.CompletedProcess[str]:
    """Invoke PyInstaller using the current interpreter."""
    command = [sys.executable, "-m", "PyInstaller", *py_args]
    print(f"[INFO] Running: {' '.join(command)}")
    return subprocess.run(command, text=True, capture_output=True)


def build_executable() -> bool:
    """Build the console CLI executable."""
    pyinstaller_args: List[str] = [
        "--onefile",
        "--name",
        "web-sentinel",
        "--console",
        "--hidden-import",
        "web_sentinel.checks.headers",
        "--hidden-import",
        "web_sentinel.checks.tls",
        "--hidden-import",
        "web_sentinel.checks.injection",
        "--hidden-import",
        "web_sentinel.checks.static_analysis",
        "--hidden-import",
        "web_sentinel.checks.third_party",
        "--exclude-module",
        "pytest",
        "--exclude-module",
        "test",
    ]
    _extend_with_data(pyinstaller_args)
    pyinstaller_args.append(str(REPO_ROOT / "web_sentinel" / "cli.py"))

    result = _run_pyinstaller(pyinstaller_args)
    if result.returncode == 0:
        print("[OK] CLI executable available in dist/web-sentinel.exe")
        return True

    print("[ERROR] PyInstaller failed for CLI build:")
    if result.stdout:
        print(result.stdout)
    if result.stderr:
        print(result.stderr)
    return False


def create_gui_executable() -> bool:
    """Build the GUI executable."""
    pyinstaller_args: List[str] = [
        "--onefile",
        "--name",
        "web-sentinel-gui",
        "--windowed",
        "--hidden-import",
        "web_sentinel.gui.modern_tabbed_window",
        "--hidden-import",
        "web_sentinel.gui.sections.license",
        "--hidden-import",
        "web_sentinel.gui.sections.sast",
        "--hidden-import",
        "web_sentinel.gui.sections.history",
        "--hidden-import",
        "web_sentinel.gui.sections.payment",
    ]
    _extend_with_data(pyinstaller_args)
    pyinstaller_args.append(str(REPO_ROOT / "web_sentinel" / "gui" / "app.py"))

    result = _run_pyinstaller(pyinstaller_args)
    if result.returncode == 0:
        print("[OK] GUI executable available in dist/web-sentinel-gui.exe")
        return True

    print("[ERROR] PyInstaller failed for GUI build:")
    if result.stdout:
        print(result.stdout)
    if result.stderr:
        print(result.stderr)
    return False


def main() -> int:
    cli_ok = build_executable()
    gui_ok = cli_ok and create_gui_executable()
    if cli_ok and gui_ok:
        print("\n[READY] Distribution artefacts:")
        print("  - dist/web-sentinel.exe (CLI)")
        print("  - dist/web-sentinel-gui.exe (GUI)")
        return 0
    return 1


if __name__ == "__main__":
    sys.exit(main())
