#!/usr/bin/env python3
"""Run repository validation commands for the Harness template."""

from __future__ import annotations

import json
import os
import subprocess
import sys
from pathlib import Path


DEFAULT_NPM_ORDER = ("lint", "build", "test")


def load_env_commands() -> list[str]:
    raw = os.environ.get("HARNESS_VALIDATION_COMMANDS", "")
    return [line.strip() for line in raw.splitlines() if line.strip()]


def load_npm_commands(root: Path) -> list[str]:
    package_json = root / "package.json"
    if not package_json.exists():
        return []

    try:
        payload = json.loads(package_json.read_text(encoding="utf-8"))
    except json.JSONDecodeError:
        return []

    scripts = payload.get("scripts", {})
    if not isinstance(scripts, dict):
        return []

    commands = []
    for name in DEFAULT_NPM_ORDER:
        value = scripts.get(name)
        if isinstance(value, str) and value.strip():
            commands.append(f"npm run {name}")
    return commands


def quote_path(path: Path) -> str:
    return f'"{path}"'


def preferred_python(root: Path) -> Path:
    candidates = [
        root / "venv" / "python.exe",
        root / "venv" / "Scripts" / "python.exe",
        root / ".venv" / "Scripts" / "python.exe",
        root / ".venv" / "bin" / "python",
    ]
    for candidate in candidates:
        if candidate.exists():
            return candidate
    return Path(sys.executable)


def load_python_commands(root: Path) -> list[str]:
    scripts_dir = root / "scripts"
    if not scripts_dir.exists():
        return []

    python = quote_path(preferred_python(root))
    py_compile_targets = [
        path
        for path in [
            scripts_dir / "execute.py",
            scripts_dir / "validate_workspace.py",
        ]
        if path.exists()
    ]

    commands: list[str] = []
    if py_compile_targets:
        rel_targets = " ".join(str(path.relative_to(root)) for path in py_compile_targets)
        commands.append(f"{python} -m py_compile {rel_targets}")

    test_targets = sorted(path for path in scripts_dir.glob("test_*.py") if path.is_file())
    tests_dir = root / "tests"
    if tests_dir.exists():
        test_targets.append(tests_dir)
    if test_targets:
        rel_tests = " ".join(str(path.relative_to(root)) for path in test_targets)
        commands.append(f"{python} -m pytest {rel_tests}")

    return commands


def discover_commands(root: Path) -> list[str]:
    env_commands = load_env_commands()
    if env_commands:
        return env_commands
    npm_commands = load_npm_commands(root)
    if npm_commands:
        return npm_commands
    return load_python_commands(root)


def run_command(command: str, root: Path) -> subprocess.CompletedProcess:
    return subprocess.run(
        command,
        cwd=root,
        shell=True,
        capture_output=True,
        text=True,
    )


def emit_stream(prefix: str, content: str, *, stream) -> None:
    text = content.strip()
    if not text:
        return
    print(prefix, file=stream)
    print(text, file=stream)


def main() -> int:
    root = Path(__file__).resolve().parent.parent
    commands = discover_commands(root)

    if not commands:
        print("No validation commands configured.")
        print("Set HARNESS_VALIDATION_COMMANDS or add npm scripts for lint/build/test.")
        return 0

    for command in commands:
        print(f"$ {command}")
        result = run_command(command, root)
        emit_stream("[stdout]", result.stdout, stream=sys.stdout)
        emit_stream("[stderr]", result.stderr, stream=sys.stderr)
        if result.returncode != 0:
            print(f"Validation failed: {command}", file=sys.stderr)
            return result.returncode

    print("Validation succeeded.")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
