#!/usr/bin/env python3
"""ADR compliance checker for CleverAgents.

Verifies that code follows the architectural decisions recorded in ADRs.

ADR-002: Asyncio Concurrency Model
  - Async functions should use 'async def', not threading
  - No direct thread usage in application layer

ADR-003: Dependency Injection Framework
  - Services should receive dependencies via __init__
  - No direct instantiation of infrastructure in application layer

ADR-007: Repository Pattern for Persistence
  - Database access only through repository classes
  - No direct SQLAlchemy session usage in services

Usage:
    python scripts/check-adr-compliance.py
"""

import ast
import sys
from pathlib import Path


def check_adr002_async_model(src_dir: Path) -> list[str]:
    """Check ADR-002: Asyncio Concurrency Model.

    Verifies no direct threading usage in application code.
    """
    violations: list[str] = []
    app_dir = src_dir / "application"
    if not app_dir.exists():
        return violations

    for py_file in app_dir.rglob("*.py"):
        content = py_file.read_text()
        if "import threading" in content or "from threading import" in content:
            violations.append(
                f"ADR-002 violation: {py_file.relative_to(src_dir)} "
                "imports threading directly. Use asyncio instead."
            )
    return violations


def check_adr003_dependency_injection(src_dir: Path) -> list[str]:
    """Check ADR-003: Dependency Injection Framework.

    Verifies services use constructor injection.
    """
    violations: list[str] = []
    services_dir = src_dir / "application" / "services"
    if not services_dir.exists():
        return violations

    for py_file in services_dir.rglob("*.py"):
        if py_file.name.startswith("__"):
            continue
        try:
            tree = ast.parse(py_file.read_text())
        except SyntaxError:
            continue

        for node in ast.walk(tree):
            if isinstance(node, ast.ClassDef):
                # Check if class has __init__ with parameters (DI)
                has_init = False
                for item in node.body:
                    if isinstance(item, ast.FunctionDef) and item.name == "__init__":
                        has_init = True
                        # Check for at least one parameter beyond self
                        if len(item.args.args) < 2:
                            violations.append(
                                f"ADR-003 note: {py_file.relative_to(src_dir)}:"
                                f"{node.lineno} class {node.name} has __init__ "
                                "with no injected dependencies"
                            )
                if not has_init and node.body:
                    # Services without __init__ may be okay if they're utility classes
                    pass
    return violations


def check_adr007_repository_pattern(src_dir: Path) -> list[str]:
    """Check ADR-007: Repository Pattern for Persistence.

    Verifies no direct SQLAlchemy session usage in service layer.
    """
    violations: list[str] = []
    services_dir = src_dir / "application" / "services"
    if not services_dir.exists():
        return violations

    for py_file in services_dir.rglob("*.py"):
        content = py_file.read_text()
        # Check for direct session imports
        if "from sqlalchemy" in content:
            violations.append(
                f"ADR-007 violation: {py_file.relative_to(src_dir)} "
                "imports SQLAlchemy directly. Use repository pattern instead."
            )
        if "session.query" in content or "session.execute" in content:
            violations.append(
                f"ADR-007 violation: {py_file.relative_to(src_dir)} "
                "uses session directly. Access data through repositories."
            )
    return violations


def main() -> int:
    """Run all ADR compliance checks."""
    src_dir = Path("src/cleveragents")
    if not src_dir.exists():
        print("Error: src/cleveragents directory not found")
        return 1

    all_violations: list[str] = []

    print("Checking ADR-002: Asyncio Concurrency Model...")
    all_violations.extend(check_adr002_async_model(src_dir))

    print("Checking ADR-003: Dependency Injection Framework...")
    all_violations.extend(check_adr003_dependency_injection(src_dir))

    print("Checking ADR-007: Repository Pattern for Persistence...")
    all_violations.extend(check_adr007_repository_pattern(src_dir))

    if all_violations:
        print(f"\nFound {len(all_violations)} ADR compliance issue(s):")
        for violation in all_violations:
            print(f"  - {violation}")
        return 1

    print("\nAll ADR compliance checks passed.")
    return 0


if __name__ == "__main__":
    sys.exit(main())
