"""Canonical repository name derivation and tracer persistence."""

from __future__ import annotations

import subprocess
from pathlib import Path

from adw_modules.git_helper import derive_repo_name
from adw_modules.tracer import Tracer


def _git(repo: Path, *args: str) -> str:
    result = subprocess.run(["git", "-C", str(repo), *args], check=True,
                            capture_output=True, text=True)
    return result.stdout.strip()


def _init_repo(path: Path) -> Path:
    path.mkdir(parents=True)
    _git(path, "init", "-b", "main")
    _git(path, "config", "user.email", "factory@test")
    _git(path, "config", "user.name", "Factory Test")
    (path / "tracked.txt").write_text("base\n")
    _git(path, "add", "tracked.txt")
    _git(path, "commit", "-m", "base")
    return path


def test_derive_repo_name_from_main_checkout(tmp_path: Path) -> None:
    repo = _init_repo(tmp_path / "overdeck")
    assert derive_repo_name(repo) == "overdeck"


def test_derive_repo_name_from_linked_worktree(tmp_path: Path) -> None:
    repo = _init_repo(tmp_path / "overdeck")
    worktree = tmp_path / "overdeck" / ".worktrees" / "cluster-machines-hero"
    _git(repo, "worktree", "add", str(worktree), "-b", "factory/cluster-machines-hero")

    assert derive_repo_name(worktree) == "overdeck"
    assert derive_repo_name(repo) == "overdeck"


def test_derive_repo_name_falls_back_to_checkout_basename(tmp_path: Path) -> None:
    plain = tmp_path / "cluster-machines-hero"
    plain.mkdir()
    assert derive_repo_name(plain) == "cluster-machines-hero"
    assert derive_repo_name(None) is None


def test_fresh_db_migrates_repo_name_column(tmp_path: Path) -> None:
    tracer = Tracer(tmp_path / "fresh.db", tmp_path / "events.jsonl")
    try:
        columns = {row[1] for row in tracer.conn.execute("PRAGMA table_info(sessions)")}
        assert "repo_name" in columns
    finally:
        tracer.conn.close()


def test_session_start_stores_repo_path_and_canonical_repo_name(tmp_path: Path) -> None:
    repo = _init_repo(tmp_path / "overdeck")
    worktree = tmp_path / "overdeck" / ".worktrees" / "cluster-machines-hero"
    _git(repo, "worktree", "add", str(worktree), "-b", "factory/cluster-machines-hero")

    tracer = Tracer(tmp_path / "sssf.db", tmp_path / "events.jsonl")
    try:
        tracer.session_start("run1", "alice", repo=worktree)
        row = tracer.conn.execute(
            "SELECT repo, repo_name FROM sessions WHERE adw_id='run1'",
        ).fetchone()
    finally:
        tracer.conn.close()

    assert row == (str(worktree.resolve()), "overdeck")


def test_session_join_backfills_repo_name_without_overwriting_repo(tmp_path: Path) -> None:
    repo = _init_repo(tmp_path / "overdeck")
    worktree = tmp_path / "overdeck" / ".worktrees" / "cluster-machines-hero"
    _git(repo, "worktree", "add", str(worktree), "-b", "factory/cluster-machines-hero")

    tracer = Tracer(tmp_path / "sssf.db", tmp_path / "events.jsonl")
    try:
        tracer.session_start("pinned", "alice", repo=worktree, adw_name="adw_plan")
        tracer.session_start("pinned", "alice", repo=worktree, adw_name="adw_build")
        row = tracer.conn.execute(
            "SELECT repo, repo_name FROM sessions WHERE adw_id='pinned'",
        ).fetchone()
    finally:
        tracer.conn.close()

    assert row == (str(worktree.resolve()), "overdeck")
