"""ORCH-057 D1: actionable worktree error on a legacy-ownership permission failure.

TC-01 / TC-02 (04-test-plan.yaml): a permission-class ``git worktree add`` /
``os.makedirs`` failure must surface an actionable RuntimeError (cause + healing
command + INFRA.md ref), while a NON-permission failure keeps the prior raw-stderr
contract (no meaning substitution). No real chown / no writes to /repos — failures
are simulated via monkeypatched ``subprocess.run`` / ``os.makedirs``.
"""
import os
import tempfile

import pytest

_test_db = os.path.join(tempfile.gettempdir(), "test_orchestrator_wt_perm.db")
os.environ["ORCH_DB_PATH"] = _test_db
os.environ["ORCH_REPOS_DIR"] = tempfile.gettempdir()
os.environ["ORCH_GITEA_TOKEN"] = "test-token"
os.environ["ORCH_PLANE_API_TOKEN"] = "test-token"

from src import git_worktree
from src.git_worktree import ensure_worktree


class _R:
    """Minimal CompletedProcess stand-in."""

    def __init__(self, returncode, stderr=""):
        self.returncode = returncode
        self.stderr = stderr
        self.stdout = ""


@pytest.fixture
def main_repo(tmp_path, monkeypatch):
    """A bare-minimum main clone dir so ensure_worktree gets past the existence check.

    repos_dir/<repo> must be a directory; worktrees_dir points at a fresh tmp path.
    The actual git calls are monkeypatched per-test.
    """
    repo = "orchestrator"
    repos_dir = tmp_path / "repos"
    (repos_dir / repo).mkdir(parents=True)
    monkeypatch.setattr(git_worktree.settings, "repos_dir", str(repos_dir))
    monkeypatch.setattr(git_worktree.settings, "worktrees_dir", str(tmp_path / "repos" / "_wt"))
    monkeypatch.setattr(git_worktree.settings, "fs_normalize_enabled", True)
    return repo


def test_tc01_permission_git_fatal_becomes_actionable(main_repo, monkeypatch):
    """TC-01: a git-fatal 'could not create leading directories / Permission denied'
    raises an actionable RuntimeError (diagnosis + chown), not the raw git stderr."""
    perm_stderr = (
        "fatal: could not create leading directories of "
        "'/repos/_wt/orchestrator/x': Permission denied"
    )

    def fake_run(cmd, *a, **k):
        # fetch -> ok; worktree add (both forms) -> permission fatal.
        if "fetch" in cmd:
            return _R(0)
        if "worktree" in cmd and "add" in cmd:
            return _R(128, perm_stderr)
        return _R(0)

    monkeypatch.setattr(git_worktree.subprocess, "run", fake_run)

    with pytest.raises(RuntimeError) as ei:
        ensure_worktree(main_repo, "feature/x")
    msg = str(ei.value)
    # Actionable: names the cause + the healing command + the INFRA procedure...
    assert "legacy root-owned" in msg.lower()
    assert "chown" in msg.lower()
    assert "INFRA.md" in msg
    # ...and is NOT merely the raw "git worktree add failed" passthrough.
    assert "git worktree add failed" not in msg


def test_tc01_makedirs_permission_error_becomes_actionable(main_repo, monkeypatch):
    """TC-01 (sibling path): a PermissionError from os.makedirs (creating the leading
    worktree dir) is also turned into the actionable RuntimeError."""
    def fake_run(cmd, *a, **k):
        return _R(0)

    monkeypatch.setattr(git_worktree.subprocess, "run", fake_run)

    def boom(*a, **k):
        raise PermissionError(13, "Permission denied")

    monkeypatch.setattr(git_worktree.os, "makedirs", boom)

    with pytest.raises(RuntimeError) as ei:
        ensure_worktree(main_repo, "feature/x")
    assert "chown" in str(ei.value).lower()
    assert "legacy root-owned" in str(ei.value).lower()


def test_tc02_non_permission_error_keeps_prior_contract(main_repo, monkeypatch):
    """TC-02: a NON-permission failure (e.g. a real branch conflict) keeps the prior
    raw-stderr 'git worktree add failed' message — no meaning substitution."""
    conflict = "fatal: 'feature/x' is already checked out at '/repos/_wt/other'"

    def fake_run(cmd, *a, **k):
        if "fetch" in cmd:
            return _R(0)
        if "worktree" in cmd and "add" in cmd:
            return _R(128, conflict)
        return _R(0)

    monkeypatch.setattr(git_worktree.subprocess, "run", fake_run)

    with pytest.raises(RuntimeError) as ei:
        ensure_worktree(main_repo, "feature/x")
    msg = str(ei.value)
    assert "git worktree add failed" in msg
    assert "already checked out" in msg
    # The actionable diagnosis must NOT be injected for a non-permission error.
    assert "legacy root-owned" not in msg.lower()


def test_tc02_killswitch_off_keeps_raw_contract_even_for_permission(main_repo, monkeypatch):
    """Kill-switch off (fs_normalize_enabled=False) -> the error contract is byte-for-
    byte as before ORCH-057 even for a permission failure (raw stderr passthrough)."""
    monkeypatch.setattr(git_worktree.settings, "fs_normalize_enabled", False)
    perm_stderr = "fatal: ...: Permission denied"

    def fake_run(cmd, *a, **k):
        if "fetch" in cmd:
            return _R(0)
        if "worktree" in cmd and "add" in cmd:
            return _R(128, perm_stderr)
        return _R(0)

    monkeypatch.setattr(git_worktree.subprocess, "run", fake_run)

    with pytest.raises(RuntimeError) as ei:
        ensure_worktree(main_repo, "feature/x")
    msg = str(ei.value)
    assert "git worktree add failed" in msg
    assert "legacy root-owned" not in msg.lower()
