"""Subprocess wrappers for KiCad IPC Rust binaries."""

import os
import re
import subprocess
from pathlib import Path

# Paths to IPC binaries (built from Rust examples)
_EXAMPLES_DIR = (
    Path(__file__).resolve().parents[3]
    / "desktop"
    / "src-tauri"
    / "target"
    / "release"
    / "examples"
)
_TEST_BINARY = _EXAMPLES_DIR / "test_kicad_ipc.exe"
_LAYER_BINARY = _EXAMPLES_DIR / "ipc_set_layer.exe"


def ensure_dummy_socket():
    """Create the dummy socket file for the Windows NNG workaround."""
    temp = os.environ.get("TEMP", os.environ.get("TMP", ""))
    if temp:
        sock_dir = Path(temp) / "kicad"
        sock_dir.mkdir(exist_ok=True)
        sock_file = sock_dir / "api.sock"
        if not sock_file.exists():
            sock_file.touch()


def has_test_binary() -> bool:
    return _TEST_BINARY.exists()


def has_layer_binary() -> bool:
    return _LAYER_BINARY.exists()


def run_ipc_test() -> dict:
    """Run the full IPC test binary and parse sectioned output.

    Returns dict keyed by test number (int) with the text for that section.
    """
    if not has_test_binary():
        return {}
    ensure_dummy_socket()
    try:
        result = subprocess.run(
            [str(_TEST_BINARY)],
            capture_output=True,
            text=True,
            timeout=30,
        )
        return _parse_test_output(result.stdout)
    except Exception as e:
        return {0: f"IPC test failed: {e}"}


def set_active_layer(layer_id: int) -> dict:
    """Set KiCad's active layer via IPC."""
    if not has_layer_binary():
        return {"success": False, "output": "ipc_set_layer.exe not found"}
    ensure_dummy_socket()
    try:
        result = subprocess.run(
            [str(_LAYER_BINARY), str(layer_id)],
            capture_output=True,
            text=True,
            timeout=10,
        )
        output = result.stdout.strip() or result.stderr.strip()
        return {"success": result.returncode == 0, "output": output}
    except Exception as e:
        return {"success": False, "output": str(e)}


def _parse_test_output(stdout: str) -> dict:
    """Parse test_kicad_ipc.exe output into sections by [N] headers."""
    sections = {}
    current_key = None
    current_lines = []
    for line in stdout.splitlines():
        match = re.match(r"\[(\d+)\]", line)
        if match:
            if current_key is not None:
                sections[current_key] = "\n".join(current_lines)
            current_key = int(match.group(1))
            current_lines = [line]
        elif current_key is not None:
            current_lines.append(line)
    if current_key is not None:
        sections[current_key] = "\n".join(current_lines)
    return sections
