"""Prerequisite checks for demo scaffolding.

Each check uses subprocess.run to detect tool version.
No UI code — returns structured PrereqResult objects.
"""

from __future__ import annotations

import re
import subprocess

from exokit.core.models import PrereqResult


def _run_version_command(command: list[str]) -> tuple[bool, str]:
    """Run a version command and return (success, output).

    Returns (False, error_message) if the command fails or is not found.
    """
    try:
        result = subprocess.run(  # noqa: S603
            command,
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0:
            return True, result.stdout.strip()
        return False, result.stderr.strip()
    except FileNotFoundError:
        return False, f"Command not found: {command[0]}"
    except subprocess.TimeoutExpired:
        return False, f"Command timed out: {' '.join(command)}"


def _extract_version(output: str) -> str | None:
    """Extract a version string (e.g. 1.2.3) from command output."""
    match = re.search(r"\d+\.\d+(?:\.\d+)?", output)
    if match:
        return match.group(0)
    return None


def check_databricks_cli() -> PrereqResult:
    """Check if the Databricks CLI is installed and accessible."""
    success, output = _run_version_command(["databricks", "--version"])
    if success:
        version = _extract_version(output)
        return PrereqResult(
            name="databricks-cli",
            passed=True,
            message=f"Databricks CLI found: {output}",
            version=version,
        )
    return PrereqResult(
        name="databricks-cli",
        passed=False,
        message=f"Databricks CLI not found: {output}",
    )


def check_uv() -> PrereqResult:
    """Check if uv package manager is installed."""
    success, output = _run_version_command(["uv", "--version"])
    if success:
        version = _extract_version(output)
        return PrereqResult(
            name="uv",
            passed=True,
            message=f"uv found: {output}",
            version=version,
        )
    return PrereqResult(
        name="uv",
        passed=False,
        message=f"uv not found: {output}",
    )


def check_node() -> PrereqResult:
    """Check if Node.js is installed."""
    success, output = _run_version_command(["node", "--version"])
    if success:
        version = _extract_version(output)
        return PrereqResult(
            name="node",
            passed=True,
            message=f"Node.js found: {output}",
            version=version,
        )
    return PrereqResult(
        name="node",
        passed=False,
        message=f"Node.js not found: {output}",
    )


def check_apx() -> PrereqResult:
    """Check if APX CLI is installed."""
    success, output = _run_version_command(["apx", "--version"])
    if success:
        version = _extract_version(output)
        return PrereqResult(
            name="apx",
            passed=True,
            message=f"APX found: {output}",
            version=version,
        )
    return PrereqResult(
        name="apx",
        passed=False,
        message=f"APX not found: {output}",
    )


def check_databricks_auth(profile: str = "DEFAULT") -> PrereqResult:
    """Check if Databricks authentication is configured for the given profile."""
    success, output = _run_version_command(["databricks", "auth", "describe", "--profile", profile])
    if success:
        return PrereqResult(
            name=f"databricks-auth-{profile}",
            passed=True,
            message=f"Databricks auth configured for profile '{profile}'",
        )
    return PrereqResult(
        name=f"databricks-auth-{profile}",
        passed=False,
        message=f"Databricks auth not configured for profile '{profile}': {output}",
    )


def check_databricks_profiles() -> PrereqResult:
    """Check that at least one Databricks CLI profile exists in ~/.databrickscfg."""
    import configparser
    from pathlib import Path

    cfg_path = Path.home() / ".databrickscfg"
    if not cfg_path.exists():
        return PrereqResult(
            name="databricks-profiles",
            passed=False,
            message=("No ~/.databrickscfg found. Run: databricks configure --profile <name>"),
        )

    cfg = configparser.ConfigParser()
    cfg.read(cfg_path)
    profiles = list(cfg.sections())
    if cfg.defaults():
        profiles.insert(0, "DEFAULT")

    if not profiles:
        return PrereqResult(
            name="databricks-profiles",
            passed=False,
            message=(
                "~/.databrickscfg exists but has no profiles. "
                "Run: databricks configure --profile <name>"
            ),
        )

    return PrereqResult(
        name="databricks-profiles",
        passed=True,
        message=f"Found {len(profiles)} profile(s): {', '.join(profiles[:5])}",
        version=str(len(profiles)),
    )


def check_ai_dev_kit() -> PrereqResult:
    """Check if the Databricks AI Dev Kit MCP server is installed."""
    from pathlib import Path

    kit_path = Path.home() / ".ai-dev-kit"
    venv_python = kit_path / ".venv" / "bin" / "python"
    server_script = kit_path / "repo" / "databricks-mcp-server" / "run_server.py"

    if venv_python.exists() and server_script.exists():
        return PrereqResult(
            name="ai-dev-kit",
            passed=True,
            message=f"MCP server found at {kit_path}",
        )

    return PrereqResult(
        name="ai-dev-kit",
        passed=False,
        message=(
            "Databricks MCP server not installed. Install with:\n"
            "  bash <(curl -sL https://raw.githubusercontent.com/"
            "databricks-solutions/ai-dev-kit/main/install.sh)"
        ),
    )


def check_all(databricks_profile: str = "DEFAULT") -> list[PrereqResult]:
    """Run all prerequisite checks and return results.

    Args:
        databricks_profile: The Databricks CLI profile to check auth for.

    Returns:
        List of PrereqResult for each check.
    """
    return [
        check_databricks_cli(),
        check_databricks_profiles(),
        check_uv(),
        check_node(),
        check_apx(),
        check_ai_dev_kit(),
        check_databricks_auth(profile=databricks_profile),
    ]
