#!/usr/bin/env python3
"""
Completion Validator Hook
Implements quality gates before task completion from Claude Collective v9.4.2

Validates that all required quality gates are met before allowing Claude to stop:
- Tests are passing (TDD enforcement)
- Static analysis is clean
- Artifacts are properly archived
- Documentation is updated where needed
"""

import json
import subprocess
import sys
from pathlib import Path


def run_tests() -> tuple[bool | None, str, str]:
    """Run project tests and return results."""
    test_commands = [
        ["npm", "test"],
        ["yarn", "test"],
        ["pytest"],
        ["python", "-m", "pytest"],
        ["cargo", "test"],
        ["go", "test", "./..."],
        ["mvn", "test"],
        ["gradle", "test"],
    ]

    for cmd in test_commands:
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
            if result.returncode == 0:
                return True, f"Tests passed with {cmd[0]}", result.stdout
            else:
                return False, f"Tests failed with {cmd[0]}", result.stderr
        except (FileNotFoundError, subprocess.TimeoutExpired):
            continue

    return None, "No test runner found", ""


def check_static_analysis() -> tuple[bool, list[str]]:
    """Check if static analysis is clean."""
    # Check for common linting/analysis tools
    checks = [
        (["eslint", "."], "ESLint"),
        (["ruff", "check", "."], "Ruff"),
        (["pylint", "."], "Pylint"),
        (["cargo", "clippy"], "Clippy"),
        (["go", "vet", "./..."], "Go vet"),
    ]

    issues = []
    for cmd, tool_name in checks:
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            if result.returncode != 0 and result.stderr:
                issues.append(f"{tool_name}: {result.stderr[:200]}")
        except (FileNotFoundError, subprocess.TimeoutExpired):
            continue

    return len(issues) == 0, issues


def check_recent_changes() -> list[str]:
    """Check what files have been recently modified."""
    try:
        result = subprocess.run(
            ["git", "diff", "--name-only", "HEAD~1"],
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0:
            return result.stdout.strip().split("\n") if result.stdout.strip() else []
    except (FileNotFoundError, subprocess.TimeoutExpired):
        pass

    return []


def check_documentation_needs(changed_files: list[str]) -> list[str]:
    """Check if documentation updates might be needed."""
    docs_needed = []

    for file_path in changed_files:
        if not file_path:
            continue

        # Check if API files were changed
        if any(
            pattern in file_path.lower()
            for pattern in ["api", "endpoint", "route", "service"]
        ):
            docs_needed.append(f"API documentation for {file_path}")

        # Check if public interfaces were changed
        if any(pattern in file_path for pattern in ["interface", "public", "export"]):
            docs_needed.append(f"Interface documentation for {file_path}")

    return docs_needed


def check_artifacts_status() -> tuple[bool, str]:
    """Check if artifacts are properly managed."""
    manifest_path = Path("artifacts/STATE_MANIFEST.md")
    if not manifest_path.exists():
        return False, "No STATE_MANIFEST.md found"

    # Check if manifest was recently updated
    try:
        result = subprocess.run(
            ["git", "log", "-1", "--format=%cr", str(manifest_path)],
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0:
            last_update = result.stdout.strip()
            if "hours ago" in last_update or "minutes ago" in last_update:
                return True, f"Artifacts updated {last_update}"
    except (FileNotFoundError, subprocess.TimeoutExpired):
        pass

    return True, "Artifacts status unclear"


def main() -> None:
    try:
        input_data = json.load(sys.stdin)
    except json.JSONDecodeError as e:
        print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
        sys.exit(1)

    stop_hook_active = input_data.get("stop_hook_active", False)

    # Avoid infinite loops
    if stop_hook_active:
        sys.exit(0)

    print("🔍 COMPLETION VALIDATOR: Running quality gates...")

    validation_failures = []
    warnings = []

    # 1. Test Validation (TDD Enforcement)
    test_result, test_message, test_output = run_tests()
    if test_result is False:
        validation_failures.append(f"❌ Tests failing: {test_message}")
    elif test_result is True:
        print(f"✅ Tests passed: {test_message}")
    else:
        warnings.append(f"⚠️  No tests found: {test_message}")

    # 2. Static Analysis Validation
    static_clean, static_issues = check_static_analysis()
    if not static_clean:
        validation_failures.append(
            f"❌ Static analysis issues: {'; '.join(static_issues[:3])}"
        )
    else:
        print("✅ Static analysis clean")

    # 3. Artifact Management Check
    artifacts_ok, artifacts_message = check_artifacts_status()
    if artifacts_ok:
        print(f"✅ Artifacts managed: {artifacts_message}")
    else:
        warnings.append(f"⚠️  Artifacts: {artifacts_message}")

    # 4. Documentation Check
    changed_files = check_recent_changes()
    docs_needed = check_documentation_needs(changed_files)
    if docs_needed:
        warnings.append(f"⚠️  Consider updating: {', '.join(docs_needed[:2])}")

    # Determine if we should block completion
    if validation_failures:
        failure_message = (
            "QUALITY GATES FAILED - Cannot complete task:\n\n"
            + "\n".join(validation_failures)
        )

        if warnings:
            failure_message += "\n\nAdditional warnings:\n" + "\n".join(warnings)

        failure_message += "\n\nPlease address these issues before task completion."

        output = {"decision": "block", "reason": failure_message}
        print(json.dumps(output))
        sys.exit(0)

    # Show warnings but allow completion
    if warnings:
        warning_message = "Task quality check complete with warnings:\n" + "\n".join(
            warnings
        )
        print(warning_message)

    print("✅ COMPLETION VALIDATOR: All quality gates passed")
    sys.exit(0)


if __name__ == "__main__":
    main()
