import subprocess

from app.config import Settings
from app.git_adapter import CommitRequest, GitAdapter, GitAdapterError


def _copy_schema_files(tmp_path) -> None:
    (tmp_path / "schemas").mkdir()
    source_schema = Settings().repo_root / "schemas"
    for schema in source_schema.glob("*.json"):
        (tmp_path / "schemas" / schema.name).write_text(schema.read_text(), encoding="utf-8")


def _create_empty_inventory(tmp_path) -> None:
    (tmp_path / "40-inventory").mkdir()
    for name in [
        "backups",
        "databases",
        "domains",
        "endpoints",
        "hardware",
        "hosts",
        "integrations",
        "networks",
        "projects",
        "services",
        "traffic-routes",
        "virtual-machines",
    ]:
        (tmp_path / "40-inventory" / f"{name}.yml").write_text("---\n[]\n", encoding="utf-8")


def _init_git_repo(tmp_path) -> None:
    subprocess.run(["git", "init"], cwd=tmp_path, check=True, stdout=subprocess.PIPE)
    subprocess.run(["git", "config", "user.email", "test@example.invalid"], cwd=tmp_path, check=True)
    subprocess.run(["git", "config", "user.name", "Test User"], cwd=tmp_path, check=True)


def _write_valid_doc(tmp_path, path: str) -> None:
    target = tmp_path / path
    target.parent.mkdir(parents=True, exist_ok=True)
    target.write_text(
        "---\n"
        "owner: gmikcon\n"
        "status: active\n"
        "last_reviewed: 2026-05-09\n"
        "review_interval: 90d\n"
        "confidence: medium\n"
        "source_of_truth: test\n"
        "---\n\n"
        "# Test\n",
        encoding="utf-8",
    )


def test_rejects_denied_paths(tmp_path) -> None:
    adapter = GitAdapter(Settings(tmp_path))

    try:
        adapter._validate_paths([".codex"])
    except GitAdapterError as exc:
        assert "not allowed" in str(exc)
    else:
        raise AssertionError("Expected GitAdapterError")


def test_commit_blocks_when_validation_fails(tmp_path) -> None:
    _init_git_repo(tmp_path)
    adapter = GitAdapter(Settings(tmp_path))
    (tmp_path / "README.md").write_text("README\n", encoding="utf-8")

    try:
        adapter.commit(CommitRequest(summary="Test commit", files=["README.md"]))
    except GitAdapterError as exc:
        assert "validation failed" in str(exc)
    else:
        raise AssertionError("Expected GitAdapterError")


def test_commit_selected_files(tmp_path) -> None:
    _init_git_repo(tmp_path)
    _copy_schema_files(tmp_path)
    _create_empty_inventory(tmp_path)
    _write_valid_doc(tmp_path, "10-systems/test.md")
    adapter = GitAdapter(Settings(tmp_path))

    result = adapter.commit(
        CommitRequest(
            summary="Add test documentation",
            files=[
                "10-systems/test.md",
                "40-inventory",
                "schemas",
            ],
        )
    )

    assert result["status"] == "committed"
    assert "10-systems/test.md" in result["files"]
