from __future__ import annotations

from pathlib import Path
from unittest.mock import MagicMock

import pytest
from pygit2 import Repository, init_repository

from pygittools.tui.git_worktrees import (
	add_worktree,
	list_worktrees,
	parse_worktree_porcelain,
	remove_worktree,
)


def test_parse_worktree_porcelain() -> None:
	text = """
worktree /repo/main
HEAD abcdef1234567890
branch refs/heads/main

worktree /repo/feature
HEAD 1111111111111111
branch refs/heads/feature
locked

worktree /repo/old
prunable gitdir file points to non-existent location

""".strip()
	entries = parse_worktree_porcelain(text)
	assert len(entries) == 3
	assert entries[0].path == Path("/repo/main")
	assert entries[0].branch == "main"
	assert entries[0].head == "abcdef1234567890"
	assert entries[1].locked == ""
	assert entries[1].branch == "feature"
	assert entries[2].prunable == "gitdir file points to non-existent location"


def test_parse_detached_and_bare() -> None:
	text = """
worktree /repo/detached
HEAD deadbeef
detached

worktree /repo/bare.git
bare

""".strip()
	entries = parse_worktree_porcelain(text)
	assert entries[0].detached is True
	assert entries[0].branch is None
	assert entries[1].bare is True


def test_list_worktrees_no_workdir(monkeypatch: pytest.MonkeyPatch) -> None:
	repo = MagicMock(spec=Repository)
	repo.workdir = None
	entries, error = list_worktrees(repo)
	assert entries == []
	assert error is not None


def test_add_worktree_requires_path(repo: Repository, monkeypatch: pytest.MonkeyPatch) -> None:
	calls: list[list[str]] = []

	def fake_run(cmd: list[str], **kwargs: object) -> MagicMock:
		calls.append(cmd)
		return MagicMock(returncode=0, stdout="", stderr="")

	monkeypatch.setattr("pygittools.tui.git_worktrees.subprocess.run", fake_run)
	ok, error = add_worktree(repo, Path("../wt"), "feature")
	assert ok is True
	assert error == ""
	assert calls
	assert "-b" in calls[0] or "feature" in calls[0]


def test_remove_worktree_force(repo: Repository, monkeypatch: pytest.MonkeyPatch) -> None:
	calls: list[list[str]] = []

	def fake_run(cmd: list[str], **kwargs: object) -> MagicMock:
		calls.append(cmd)
		return MagicMock(returncode=0, stdout="", stderr="")

	monkeypatch.setattr("pygittools.tui.git_worktrees.subprocess.run", fake_run)
	ok, error = remove_worktree(repo, Path("/tmp/wt"), force=True)
	assert ok is True
	assert "--force" in calls[0]


@pytest.fixture
def repo(tmp_path: Path) -> Repository:
	repo_path = tmp_path / "repo"
	repo_path.mkdir()
	return init_repository(str(repo_path), bare=False)