# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Wiring audit -- catches dead code, broken imports, and unwired features.
Run alongside soc_checker.py in the pre-commit hook.

Usage:
    python pulse/admin/audit/wiring_check.py          -- manual run (all files)
    python pulse/admin/audit/wiring_check.py FILE.py  -- single file
"""

import ast
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent.parent.parent


def find_defined_functions(filepath: Path) -> set:
    """Find all public function names defined at module level in a file."""
    try:
        tree = ast.parse(filepath.read_text(encoding="utf-8"))
        return {
            node.name
            for node in ast.walk(tree)
            if isinstance(node, ast.FunctionDef) and not node.name.startswith("_")
        }
    except Exception:
        return set()


def find_imported_names(filepath: Path) -> set:
    """Find all names imported from other modules in a file."""
    try:
        tree = ast.parse(filepath.read_text(encoding="utf-8"))
        names = set()
        for node in ast.walk(tree):
            if isinstance(node, ast.ImportFrom) and node.names:
                for alias in node.names:
                    names.add(alias.name)
        return names
    except Exception:
        return set()


def check_function_has_callers(func_name: str, defining_file: Path) -> bool:
    """Check if a function defined in defining_file is imported or referenced elsewhere."""
    for py_file in ROOT.rglob("*.py"):
        if py_file == defining_file:
            continue
        if "__pycache__" in str(py_file):
            continue
        try:
            content = py_file.read_text(encoding="utf-8")
            if func_name in content:
                return True
        except Exception:
            continue
    return False


def run_wiring_check(changed_files: list = None) -> dict:
    """Run wiring check on files. Returns {warnings: [...], dead_code: [...]}."""
    warnings = []
    dead_code = []

    if changed_files:
        target_files = [Path(f) if isinstance(f, str) else f for f in changed_files]
    else:
        target_files = [
            p for p in (ROOT / "pulse").rglob("*.py")
            if "__pycache__" not in str(p)
        ]

    for filepath in target_files:
        if not filepath.exists():
            continue
        functions = find_defined_functions(filepath)
        for func in functions:
            if not check_function_has_callers(func, filepath):
                try:
                    rel = filepath.relative_to(ROOT)
                except ValueError:
                    rel = filepath
                dead_code.append(
                    f"{rel}:{func}() -- defined but never imported elsewhere"
                )

    return {"warnings": warnings, "dead_code": dead_code}


def main():
    """CLI entry point for manual run or pre-commit hook."""
    changed_files = None
    if len(sys.argv) > 1:
        changed_files = [Path(p) for p in sys.argv[1:] if p.endswith(".py")]

    result = run_wiring_check(changed_files)

    if result["dead_code"]:
        print(f"  WIRING CHECK: {len(result['dead_code'])} potentially unwired functions")
        for dc in result["dead_code"][:10]:
            print(f"    ? {dc}")
    else:
        print("  WIRING CHECK: no dead code found")

    # Advisory only -- never block commits
    sys.exit(0)


if __name__ == "__main__":
    main()
