#!/usr/bin/env python3
"""
Contract Validation Hook
Implements Contract-Driven Parallelism from Claude Collective v9.4.2

Ensures that contracts exist before implementation begins and validates
that the current action aligns with the contract-driven workflow.
"""

import json
import re
import sys
from pathlib import Path


def find_contract_files() -> list[str]:
    """Find existing contract files in the project."""
    contract_patterns = [
        "contracts/**/*.md",
        "**/CONTRACT.md",
        "**/contracts.md",
        "specs/**/*.md",
        "requirements/**/*.md",
    ]

    contracts: list[str] = []
    for pattern in contract_patterns:
        contracts.extend(str(p) for p in Path(".").glob(pattern))

    return [str(c) for c in contracts]


def find_task_board() -> str | None:
    """Find the task board file."""
    possible_locations = [
        "TASK_BOARD.md",
        "artifacts/TASK_BOARD.md",
        "docs/TASK_BOARD.md",
        "planning/TASK_BOARD.md",
    ]

    for location in possible_locations:
        if Path(location).exists():
            return location
    return None


def check_file_has_contract_reference(file_path: str, content: str) -> bool:
    """Check if the file or its content references a contract."""
    # Look for contract references in comments
    contract_patterns = [
        r"@contract[:\s]+\w+",
        r"Contract[:\s]+\w+",
        r"implements[:\s]+\w+",
        r"according to[:\s]+\w+",
    ]

    for pattern in contract_patterns:
        if re.search(pattern, content, re.IGNORECASE):
            return True

    return False


def is_implementation_file(file_path: str) -> bool:
    """Determine if this is an implementation file that should have a contract."""
    # Skip configuration, test, and documentation files
    skip_patterns = [
        "test",
        "spec",
        "__test__",
        ".test.",
        "config",
        "setup",
        "webpack",
        "babel",
        "README",
        "CHANGELOG",
        "LICENSE",
        ".gitignore",
        ".eslintrc",
        "package.json",
        "tsconfig.json",
        "pyproject.toml",
    ]

    file_lower = file_path.lower()
    if any(pattern in file_lower for pattern in skip_patterns):
        return False

    # Check if it's a source code file
    implementation_extensions = {
        ".py",
        ".js",
        ".ts",
        ".jsx",
        ".tsx",
        ".rs",
        ".go",
        ".java",
        ".cpp",
        ".c",
    }
    return Path(file_path).suffix.lower() in implementation_extensions


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)

    tool_input = input_data.get("tool_input", {})

    file_path = tool_input.get("file_path", "")
    content = tool_input.get("content", "")

    if not file_path:
        sys.exit(0)

    # Only validate implementation files
    if not is_implementation_file(file_path):
        sys.exit(0)

    print(f"⚖️  CONTRACT VALIDATOR: Checking contract compliance for {file_path}")

    # Check if contracts exist in the project
    contracts = find_contract_files()
    task_board = find_task_board()

    if not contracts and not task_board:
        warning_msg = """
CONTRACT VALIDATION WARNING: No contracts or task board found.

According to Claude Collective v9.4.2, implementation should begin only after
contract approval.
Consider creating:
1. A TASK_BOARD.md with current epics
2. Contract files in a contracts/ directory
3. API specifications or data models

This ensures contract-driven parallelism and proper workflow coordination.
"""
        print(warning_msg, file=sys.stderr)

        # Don't block, but provide guidance
        output = {
            "continue": True,
            "reason": "Consider establishing contracts before implementation for better"
            " workflow coordination.",
        }
        print(json.dumps(output))
        sys.exit(0)

    # Check if the file references a contract
    if content and not check_file_has_contract_reference(file_path, content):
        guidance_msg = f"""
ATHENA GUIDANCE: Implementation file {file_path} should reference its governing
contract.

Add a comment referencing the relevant contract, for example:
# @contract: user_authentication_v1.2
# Implements: UserAuth API according to contract_auth_20241201.md
// Contract: payment_processing_v2.1

Available contracts: {", ".join(contracts[:5])}
"""
        print(guidance_msg)

        # Provide guidance but don't block
        output = {
            "continue": True,
            "reason": f"Consider adding contract reference to {file_path} for better"
            " traceability.",
        }
        print(json.dumps(output))

    print(f"✅ CONTRACT VALIDATOR: {file_path} validation complete")
    sys.exit(0)


if __name__ == "__main__":
    main()
