"""ASV benchmarks for built-in git tools.

Measures the performance of:
- git status, diff, log, and blame operations
- Git tool registration
- Path validation overhead
"""

from __future__ import annotations

import os
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path

try:
    from cleveragents.tool.builtins import register_git_tools
    from cleveragents.tool.builtins.git_tools import validate_repo_path
    from cleveragents.tool.registry import ToolRegistry
    from cleveragents.tool.runner import ToolRunner
except ModuleNotFoundError:
    sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
    from cleveragents.tool.builtins import register_git_tools
    from cleveragents.tool.builtins.git_tools import validate_repo_path
    from cleveragents.tool.registry import ToolRegistry
    from cleveragents.tool.runner import ToolRunner


def _git(args: list[str], cwd: str) -> None:
    """Run a git command with CI-safe environment variables.

    Sets ``safe.directory`` so git does not refuse to operate in temp
    directories owned by a different user (common in Docker / CI).
    """
    env = {
        **os.environ,
        "GIT_CONFIG_NOSYSTEM": "1",
        "GIT_TERMINAL_PROMPT": "0",
        "GIT_CONFIG_COUNT": "1",
        "GIT_CONFIG_KEY_0": "safe.directory",
        "GIT_CONFIG_VALUE_0": cwd,
    }
    subprocess.run(
        ["git", *args],
        cwd=cwd,
        capture_output=True,
        text=True,
        check=True,
        timeout=30,
        env=env,
    )


def _make_repo() -> str:
    """Create a temporary git repository with several commits."""
    repo_dir = tempfile.mkdtemp()
    _git(["init"], cwd=repo_dir)
    _git(["config", "user.email", "bench@test.com"], cwd=repo_dir)
    _git(["config", "user.name", "Bench User"], cwd=repo_dir)
    for i in range(5):
        f = Path(repo_dir) / f"file_{i}.txt"
        f.write_text(f"content line {i}\n" * 10)
        _git(["add", "."], cwd=repo_dir)
        _git(["commit", "-m", f"Commit {i}"], cwd=repo_dir)
    return repo_dir


class GitToolSuite:
    """Benchmark built-in git tool operations."""

    def setup(self) -> None:
        self.repo_dir = _make_repo()
        self.registry = ToolRegistry()
        register_git_tools(self.registry)
        self.runner = ToolRunner(self.registry)

    def teardown(self) -> None:
        shutil.rmtree(self.repo_dir, ignore_errors=True)

    def time_git_status(self) -> None:
        self.runner.execute(
            "builtin/git-status",
            {"repo_path": self.repo_dir, "_sandbox_root": self.repo_dir},
        )

    def time_git_diff(self) -> None:
        self.runner.execute(
            "builtin/git-diff",
            {"repo_path": self.repo_dir, "_sandbox_root": self.repo_dir},
        )

    def time_git_log(self) -> None:
        self.runner.execute(
            "builtin/git-log",
            {
                "repo_path": self.repo_dir,
                "max_count": 5,
                "_sandbox_root": self.repo_dir,
            },
        )

    def time_git_blame(self) -> None:
        self.runner.execute(
            "builtin/git-blame",
            {
                "repo_path": self.repo_dir,
                "path": "file_0.txt",
                "_sandbox_root": self.repo_dir,
            },
        )


class GitRegistrationSuite:
    """Benchmark git tool registration."""

    def time_register_git_tools(self) -> None:
        registry = ToolRegistry()
        register_git_tools(registry)


class PathValidationSuite:
    """Benchmark path validation overhead."""

    def time_validate_none_path(self) -> None:
        validate_repo_path(None)

    def time_validate_absolute_path(self) -> None:
        validate_repo_path("/tmp/some/path", sandbox_root=Path("/tmp"))

    def time_validate_relative_path(self) -> None:
        validate_repo_path("subdir")
