"""
TIBET Injector - Auto-inject provenance into existing code.

The magic that makes vibe code trustworthy.
"""

import ast
import re
from pathlib import Path
from typing import List, Set, Tuple


class TibetInjector:
    """
    Inject TIBET provenance into Python code.

    Automatically wraps:
    - API endpoints
    - Database operations
    - External API calls
    - Key business functions
    """

    # Patterns to detect functions that should be wrapped
    WRAP_PATTERNS = {
        "api_endpoint": [
            r"@app\.route",
            r"@router\.(get|post|put|delete|patch)",
            r"@api_view",
            r"async def \w+\(.*request",
        ],
        "database": [
            r"\.execute\(",
            r"\.query\(",
            r"session\.(add|delete|commit)",
            r"cursor\.",
        ],
        "external_api": [
            r"requests\.(get|post|put|delete)",
            r"httpx\.",
            r"aiohttp\.",
            r"urllib\.request",
        ],
        "auth": [
            r"def (login|logout|authenticate|authorize)",
            r"password",
            r"token",
            r"jwt",
        ],
    }

    def __init__(self):
        self.injected_files: List[str] = []
        self.injected_functions: List[str] = []

    def analyze(self, project_path: Path) -> dict:
        """
        Analyze project for injection points.

        Returns dict of files and functions to wrap.
        """
        injection_points = {}

        for py_file in project_path.rglob("*.py"):
            if self._should_skip(py_file):
                continue

            points = self._analyze_file(py_file)
            if points:
                injection_points[str(py_file)] = points

        return injection_points

    def _should_skip(self, path: Path) -> bool:
        """Check if path should be skipped."""
        skip = ["__pycache__", ".git", ".venv", "venv", "node_modules", "test"]
        return any(p in path.parts for p in skip)

    def _analyze_file(self, file_path: Path) -> List[dict]:
        """Analyze a single file for injection points."""
        try:
            content = file_path.read_text(encoding="utf-8", errors="ignore")
        except:
            return []

        points = []

        for category, patterns in self.WRAP_PATTERNS.items():
            for pattern in patterns:
                for match in re.finditer(pattern, content):
                    line_num = content[:match.start()].count("\n") + 1
                    points.append({
                        "category": category,
                        "pattern": pattern,
                        "line": line_num,
                        "match": match.group(),
                    })

        return points

    def inject(self, project_path: Path, dry_run: bool = True) -> dict:
        """
        Inject TIBET into project.

        Args:
            project_path: Path to project
            dry_run: If True, only report what would be done

        Returns:
            Report of injections
        """
        points = self.analyze(project_path)

        report = {
            "files_analyzed": len(points),
            "injection_points": sum(len(p) for p in points.values()),
            "dry_run": dry_run,
            "actions": [],
        }

        for file_path, file_points in points.items():
            for point in file_points:
                action = {
                    "file": file_path,
                    "line": point["line"],
                    "category": point["category"],
                    "action": f"Add @tibet_audit decorator for {point['category']}",
                }
                report["actions"].append(action)

                if not dry_run:
                    # TODO: Actually inject the decorator
                    pass

        return report

    def generate_wrapper_code(self, project_name: str) -> str:
        """
        Generate wrapper initialization code.

        Returns Python code to add to __init__.py
        """
        return f'''"""
TIBET provenance for {project_name}.
Auto-generated by tibet-forge.
"""

from tibet_core import Provider
from tibet_forge.wrappers import set_tibet_provider

# Initialize TIBET
_tibet = Provider(actor="jis:app:{project_name}")
set_tibet_provider(_tibet)

# Export for manual use
tibet = _tibet
'''
