"""Tests for gwtm.utils — git helpers and repo detection."""

from pathlib import Path

import pytest

from gwtm.utils import (
    GitCommandError,
    NotARepoError,
    WorktreeInfo,
    get_repo_context,
    list_worktrees,
    run_git,
    validate_worktree_name,
)


class TestRunGit:
    def test_simple_command(self, temp_git_repo: Path) -> None:
        result = run_git("status", cwd=temp_git_repo)
        assert "nothing to commit" in result

    def test_raises_on_failure(self, tmp_path: Path) -> None:
        with pytest.raises(GitCommandError) as exc_info:
            run_git("log", cwd=tmp_path)
        assert exc_info.value.returncode != 0

    def test_returns_stdout(self, temp_git_repo: Path) -> None:
        result = run_git("rev-parse", "--show-toplevel", cwd=temp_git_repo)
        assert Path(result) == temp_git_repo


class TestGetRepoContext:
    def test_detects_repo(self, temp_git_repo: Path) -> None:
        ctx = get_repo_context(temp_git_repo)
        assert ctx.repo_name == "test-repo"
        assert ctx.main_worktree == temp_git_repo
        assert ctx.is_inside_worktree is True

    def test_raises_outside_repo(self, tmp_path: Path) -> None:
        with pytest.raises(NotARepoError):
            get_repo_context(tmp_path)

    def test_detects_from_subdirectory(self, temp_git_repo: Path) -> None:
        sub = temp_git_repo / "subdir"
        sub.mkdir()
        ctx = get_repo_context(sub)
        assert ctx.repo_name == "test-repo"
        assert ctx.main_worktree == temp_git_repo


class TestListWorktrees:
    def test_lists_main_worktree(self, temp_git_repo: Path) -> None:
        wts = list_worktrees(temp_git_repo)
        assert len(wts) >= 1
        assert wts[0].path == temp_git_repo

    def test_detects_branch(self, temp_git_repo: Path) -> None:
        wts = list_worktrees(temp_git_repo)
        # The main worktree should be on master or main
        assert wts[0].branch in ("master", "main")


class TestValidateWorktreeName:
    def test_valid_names(self) -> None:
        assert validate_worktree_name("feature-123") == "feature-123"
        assert validate_worktree_name("my_feature") == "my_feature"
        assert validate_worktree_name("v1.0.1") == "v1.0.1"

    def test_rejects_empty(self) -> None:
        with pytest.raises(ValueError, match="cannot be empty"):
            validate_worktree_name("")

    def test_rejects_special_chars(self) -> None:
        with pytest.raises(ValueError, match="Invalid worktree name"):
            validate_worktree_name("feat/slash")

    def test_rejects_starting_with_special(self) -> None:
        with pytest.raises(ValueError, match="Invalid worktree name"):
            validate_worktree_name("-dashed")

    def test_rejects_reserved_names(self) -> None:
        with pytest.raises(ValueError, match="reserved"):
            validate_worktree_name("main")
        with pytest.raises(ValueError, match="reserved"):
            validate_worktree_name("master")
