"""Tests for git-backed user discovery without the git CLI."""

from __future__ import annotations

import hashlib
import zlib
from pathlib import Path

import pytest

from proxym.dashboard import users as users_module


EMPTY_TREE_SHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"


@pytest.fixture(autouse=True)
def _reset_user_manager():
    users_module.UserManager.reset()
    yield
    users_module.UserManager.reset()


def _write_loose_git_object(git_dir: Path, obj_type: str, body: bytes) -> str:
    raw = f"{obj_type} {len(body)}".encode("utf-8") + b"\0" + body
    sha = hashlib.sha1(raw).hexdigest()
    obj_path = git_dir / "objects" / sha[:2] / sha[2:]
    obj_path.parent.mkdir(parents=True, exist_ok=True)
    obj_path.write_bytes(zlib.compress(raw))
    return sha


def _write_commit(
    git_dir: Path,
    *,
    name: str,
    email: str,
    message: str,
    parent: str | None = None,
    timestamp: int = 1_700_000_000,
) -> str:
    lines = [f"tree {EMPTY_TREE_SHA}"]
    if parent:
        lines.append(f"parent {parent}")
    lines.extend(
        [
            f"author {name} <{email}> {timestamp} +0000",
            f"committer {name} <{email}> {timestamp} +0000",
            "",
            message,
        ]
    )
    return _write_loose_git_object(git_dir, "commit", "\n".join(lines).encode("utf-8"))


class TestGitFallbackSync:
    def test_discovers_users_from_loose_commit_objects_without_git_binary(self, tmp_path, monkeypatch):
        repo_root = tmp_path / "repo"
        git_dir = repo_root / ".git"
        (git_dir / "refs" / "heads").mkdir(parents=True)
        (git_dir / "logs" / "refs" / "heads").mkdir(parents=True)

        (git_dir / "HEAD").write_text("ref: refs/heads/main\n", encoding="utf-8")
        (git_dir / "config").write_text(
            "[user]\n\tname = Git User\n\temail = git@example.com\n",
            encoding="utf-8",
        )

        alice = _write_commit(
            git_dir,
            name="Alice Example",
            email="alice@example.com",
            message="Initial commit",
        )
        bob = _write_commit(
            git_dir,
            name="Bob Example",
            email="bob@example.com",
            message="Follow-up commit",
            parent=alice,
            timestamp=1_700_000_100,
        )
        (git_dir / "refs" / "heads" / "main").write_text(f"{bob}\n", encoding="utf-8")

        monkeypatch.chdir(repo_root)
        monkeypatch.setattr(users_module.shutil, "which", lambda _name: None)

        mgr = users_module.UserManager.get(tmp_path / "users.sqlite")

        assert mgr.find_by_email("git@example.com") is not None

        discovered = mgr.sync_from_git_log(repo_root)
        discovered_emails = {user.email for user in discovered}

        assert discovered_emails == {"alice@example.com", "bob@example.com"}
        assert {user.email for user in mgr.list_users()} == {
            "git@example.com",
            "alice@example.com",
            "bob@example.com",
        }
