"""Tests for branches-only author mutation worktree guard (#274)."""

from __future__ import annotations

import sys
import unittest
from pathlib import Path
from unittest import mock

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

import author_mutation_worktree as amw  # noqa: E402


class TestPathUnderBranches(unittest.TestCase):
    ROOT = "/repo/Gitea-Tools"

    def test_branches_subdirectory_passes(self):
        self.assertTrue(
            amw.is_path_under_branches(f"{self.ROOT}/branches/issue-274", self.ROOT)
        )

    def test_control_checkout_fails(self):
        self.assertFalse(amw.is_path_under_branches(self.ROOT, self.ROOT))

    def test_sibling_directory_fails(self):
        self.assertFalse(
            amw.is_path_under_branches("/repo/other-checkout", self.ROOT)
        )


class TestAssessAuthorMutationWorktree(unittest.TestCase):
    ROOT = "/repo/Gitea-Tools"

    def test_branches_worktree_passes(self):
        result = amw.assess_author_mutation_worktree(
            workspace_path=f"{self.ROOT}/branches/issue-274",
            project_root=self.ROOT,
            current_branch="feat/issue-274-branches-only-worktrees",
        )
        self.assertTrue(result["proven"])
        self.assertFalse(result["block"])

    def test_control_checkout_blocks(self):
        result = amw.assess_author_mutation_worktree(
            workspace_path=self.ROOT,
            project_root=self.ROOT,
            current_branch="master",
        )
        self.assertFalse(result["proven"])
        self.assertTrue(result["block"])
        self.assertIn("control checkout", result["reasons"][0])

    def test_drifted_control_branch_blocks(self):
        result = amw.assess_author_mutation_worktree(
            workspace_path=self.ROOT,
            project_root=self.ROOT,
            current_branch="feat/some-task",
        )
        self.assertTrue(result["block"])
        self.assertTrue(any("drift" in r for r in result["reasons"]))

    def test_branches_worktree_as_project_root_passes(self):
        """MCP launched from a branches/ worktree uses that path as PROJECT_ROOT."""
        worktree_root = f"{self.ROOT}/branches/issue-274"
        result = amw.assess_author_mutation_worktree(
            workspace_path=worktree_root,
            project_root=worktree_root,
            current_branch="feat/issue-274-branches-only-worktrees",
        )
        self.assertTrue(result["proven"])
        self.assertFalse(result["block"])


class TestPreflightIntegration(unittest.TestCase):
    def test_verify_preflight_blocks_control_checkout_with_test_porcelain(self):
        import mcp_server

        mcp_server._preflight_whoami_called = True
        mcp_server._preflight_capability_called = True
        mcp_server._preflight_resolved_role = "author"
        mcp_server._preflight_resolved_task = None
        control_root = "/repo/Gitea-Tools"
        with mock.patch.object(mcp_server, "PROJECT_ROOT", control_root):
            with mock.patch.object(mcp_server, "_enforce_root_checkout_guard"):
                with mock.patch(
                    "gitea_mcp_server._session_author_lock_worktree",
                    return_value=None,
                ):
                    with mock.patch(
                        "gitea_auth.get_profile",
                        return_value={"profile_name": "gitea-author"},
                    ):
                        with mock.patch.dict(
                            "os.environ",
                            {"GITEA_TEST_PORCELAIN": ""},
                            clear=False,
                        ):
                            with self.assertRaises(RuntimeError) as ctx:
                                mcp_server.verify_preflight_purity()
        blob = str(ctx.exception)
        self.assertTrue(
            "Branches-only mutation guard" in blob
            or "control checkout" in blob
            or "author worktree" in blob.lower()
            or "#618" in blob,
            msg=blob,
        )

    def test_verify_preflight_allows_branches_worktree(self):
        import mcp_server

        mcp_server._preflight_whoami_called = True
        mcp_server._preflight_capability_called = True
        mcp_server._preflight_resolved_role = "author"
        mcp_server._preflight_resolved_task = None
        worktree = "/repo/Gitea-Tools/branches/issue-274"
        healthy_ctx = {
            "workspace_path": worktree,
            "workspace_binding_source": "worktree_path argument",
            "workspace_role_kind": "author",
            "ignored_bindings": [],
            "process_project_root": "/repo/Gitea-Tools",
            "canonical_repo_root": "/repo/Gitea-Tools",
            "roots_aligned": True,
            "bound_worktree_missing": False,
            "author_worktree_block": False,
            "author_worktree_reasons": [],
            "author_worktree_resolution": {
                "proven": True,
                "block": False,
                "bound_worktree_missing": False,
                "workspace_path": worktree,
                "workspace_binding_source": "worktree_path argument",
                "reasons": [],
            },
            "path_exists": True,
            "in_git_worktree_list": True,
            "inspected_git_root": worktree,
        }
        with mock.patch.object(mcp_server, "_enforce_root_checkout_guard"):
            with mock.patch.object(
                mcp_server, "_session_author_lock_worktree", return_value=None
            ):
                with mock.patch.object(
                    mcp_server,
                    "_resolve_namespace_mutation_context",
                    return_value=healthy_ctx,
                ):
                    with mock.patch.dict(
                        "os.environ",
                        {"GITEA_TEST_PORCELAIN": ""},
                        clear=False,
                    ):
                        mcp_server.verify_preflight_purity(worktree_path=worktree)


if __name__ == "__main__":
    unittest.main()