"""
Pre-commit Git hook for Warden.

Runs Warden analysis on staged files before commit.
"""

import subprocess
import sys
from pathlib import Path
from typing import List, Optional


class PreCommitHook:
    """Pre-commit hook that runs Warden on staged files."""

    HOOK_SCRIPT = """#!/usr/bin/env python3
\"\"\"
Warden pre-commit hook.

This hook runs Warden analysis on staged files before allowing a commit.
Auto-generated by Warden Infrastructure Module.
\"\"\"

import subprocess
import sys
from pathlib import Path


def get_staged_files() -> list[str]:
    \"\"\"Get list of staged Python files.\"\"\"
    result = subprocess.run(
        ["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
        capture_output=True,
        text=True,
        check=False,
    )

    if result.returncode != 0:
        return []

    files = result.stdout.strip().split("\\n")
    # Filter Python files
    python_files = [f for f in files if f.endswith(".py") and Path(f).exists()]

    return python_files


def main() -> int:
    \"\"\"Run Warden analysis on staged files.\"\"\"
    print("🛡️  Running Warden pre-commit checks...")

    staged_files = get_staged_files()

    if not staged_files:
        print("✓ No Python files staged, skipping Warden analysis.")
        return 0

    print(f"Analyzing {len(staged_files)} staged file(s)...")

    # Run Warden on staged files
    cmd = [
        "warden",
        "analyze",
        "--frame", "security",
        "--frame", "fuzz",
        "--ci",
    ] + staged_files

    result = subprocess.run(cmd, capture_output=True, text=True, check=False)

    if result.returncode != 0:
        print("❌ Warden found issues in staged files:")
        print(result.stdout)
        print("\\nCommit blocked. Fix issues or use 'git commit --no-verify' to bypass.")
        return 1

    print("✓ Warden pre-commit checks passed!")
    return 0


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

    @staticmethod
    def generate_script() -> str:
        """
        Generate pre-commit hook script content.

        Returns:
            Hook script as string
        """
        return PreCommitHook.HOOK_SCRIPT

    @staticmethod
    def install(git_dir: Path, force: bool = False) -> bool:
        """
        Install pre-commit hook.

        Args:
            git_dir: Path to .git directory
            force: Overwrite existing hook

        Returns:
            True if installed, False otherwise
        """
        hooks_dir = git_dir / "hooks"
        if not hooks_dir.exists():
            hooks_dir.mkdir(parents=True, exist_ok=True)

        hook_path = hooks_dir / "pre-commit"

        if hook_path.exists() and not force:
            return False

        hook_path.write_text(PreCommitHook.HOOK_SCRIPT)
        hook_path.chmod(0o755)  # Make executable

        return True

    @staticmethod
    def uninstall(git_dir: Path) -> bool:
        """
        Uninstall pre-commit hook.

        Args:
            git_dir: Path to .git directory

        Returns:
            True if uninstalled, False otherwise
        """
        hook_path = git_dir / "hooks" / "pre-commit"

        if not hook_path.exists():
            return False

        # Check if it's a Warden hook
        content = hook_path.read_text()
        if "Warden pre-commit hook" not in content:
            return False  # Don't remove non-Warden hooks

        hook_path.unlink()
        return True

    @staticmethod
    def is_installed(git_dir: Path) -> bool:
        """
        Check if pre-commit hook is installed.

        Args:
            git_dir: Path to .git directory

        Returns:
            True if installed, False otherwise
        """
        hook_path = git_dir / "hooks" / "pre-commit"

        if not hook_path.exists():
            return False

        content = hook_path.read_text()
        return "Warden pre-commit hook" in content

    @staticmethod
    def run(staged_files: Optional[List[str]] = None) -> int:
        """
        Run pre-commit hook logic.

        Args:
            staged_files: Optional list of staged files to analyze

        Returns:
            Exit code (0 = success, 1 = failure)
        """
        if staged_files is None:
            staged_files = PreCommitHook._get_staged_files()

        if not staged_files:
            print("✓ No Python files staged, skipping Warden analysis.")
            return 0

        print(f"🛡️  Analyzing {len(staged_files)} staged file(s)...")

        cmd = [
            "warden",
            "analyze",
            "--frame",
            "security",
            "--frame",
            "fuzz",
            "--ci",
        ] + staged_files

        result = subprocess.run(cmd, capture_output=True, text=True, check=False)

        if result.returncode != 0:
            print("❌ Warden found issues in staged files:")
            print(result.stdout)
            print(
                "\nCommit blocked. Fix issues or use 'git commit --no-verify' to bypass."
            )
            return 1

        print("✓ Warden pre-commit checks passed!")
        return 0

    @staticmethod
    def _get_staged_files() -> List[str]:
        """Get list of staged Python files."""
        result = subprocess.run(
            ["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
            capture_output=True,
            text=True,
            check=False,
        )

        if result.returncode != 0:
            return []

        files = result.stdout.strip().split("\n")
        python_files = [f for f in files if f.endswith(".py") and Path(f).exists()]

        return python_files
