"""Helper script for Robot Framework built-in git tools smoke tests."""

from __future__ import annotations

import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Any

# Ensure src is importable when run from workspace root
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))

from cleveragents.tool.builtins import register_git_tools
from cleveragents.tool.registry import ToolRegistry
from cleveragents.tool.runner import ToolRunner


def _git(args: list[str], cwd: str) -> subprocess.CompletedProcess[str]:
    """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).
    """
    import os

    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,
    }
    return 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 an initial commit."""
    repo_dir = tempfile.mkdtemp()
    _git(["init"], cwd=repo_dir)
    _git(["config", "user.email", "test@test.com"], cwd=repo_dir)
    _git(["config", "user.name", "Test User"], cwd=repo_dir)
    readme = Path(repo_dir) / "README.md"
    readme.write_text("# Test repo\n")
    _git(["add", "."], cwd=repo_dir)
    _git(["commit", "-m", "Initial commit"], cwd=repo_dir)
    return repo_dir


def _make_runner() -> ToolRunner:
    registry = ToolRegistry()
    register_git_tools(registry)
    return ToolRunner(registry)


def test_status() -> None:
    repo = _make_repo()
    try:
        runner = _make_runner()
        result = runner.execute(
            "builtin/git-status",
            {"repo_path": repo, "_sandbox_root": repo},
        )
        assert result.success, f"Failed: {result.error}"
        assert "nothing to commit" in result.output["output"]
        print("git-status-ok")
    finally:
        shutil.rmtree(repo, ignore_errors=True)


def test_diff() -> None:
    repo = _make_repo()
    try:
        # Modify a file to create a diff
        f = Path(repo) / "README.md"
        f.write_text("# Modified\n")
        runner = _make_runner()
        result = runner.execute(
            "builtin/git-diff",
            {"repo_path": repo, "_sandbox_root": repo},
        )
        assert result.success, f"Failed: {result.error}"
        assert "Modified" in result.output["output"]
        print("git-diff-ok")
    finally:
        shutil.rmtree(repo, ignore_errors=True)


def test_log() -> None:
    repo = _make_repo()
    try:
        runner = _make_runner()
        result = runner.execute(
            "builtin/git-log",
            {"repo_path": repo, "_sandbox_root": repo},
        )
        assert result.success, f"Failed: {result.error}"
        assert "Initial commit" in result.output["output"]
        print("git-log-ok")
    finally:
        shutil.rmtree(repo, ignore_errors=True)


def test_blame() -> None:
    repo = _make_repo()
    try:
        runner = _make_runner()
        result = runner.execute(
            "builtin/git-blame",
            {"repo_path": repo, "path": "README.md", "_sandbox_root": repo},
        )
        assert result.success, f"Failed: {result.error}"
        assert "Test User" in result.output["output"]
        print("git-blame-ok")
    finally:
        shutil.rmtree(repo, ignore_errors=True)


def test_traversal() -> None:
    repo = _make_repo()
    try:
        runner = _make_runner()
        result = runner.execute(
            "builtin/git-status",
            {"repo_path": "../../etc", "_sandbox_root": repo},
        )
        assert not result.success
        assert "traversal" in (result.error or "").lower()
        print("traversal-ok")
    finally:
        shutil.rmtree(repo, ignore_errors=True)


if __name__ == "__main__":
    cmd = sys.argv[1] if len(sys.argv) > 1 else "status"
    dispatch: dict[str, Any] = {
        "status": test_status,
        "diff": test_diff,
        "log": test_log,
        "blame": test_blame,
        "traversal": test_traversal,
    }
    fn = dispatch.get(cmd)
    if fn is None:
        print(f"Unknown command: {cmd}", file=sys.stderr)
        sys.exit(1)
    try:
        fn()
    except Exception as exc:  # pylint: disable=broad-except
        # Print to stdout so Robot Framework captures the error message
        print(f"ERROR: {type(exc).__name__}: {exc}")
        sys.exit(1)
