import sys as _sys
from pathlib import Path as _Path
_sys.path.insert(0, str(_Path(__file__).resolve().parent))
from mutation_profile_fixture import shared_mutation_env  # noqa: E402
"""Regression tests for gitea_assess_conflict_fix_push structured failures (#519)."""

import os
import sys
import unittest
from unittest.mock import patch

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

from mcp_server import (  # noqa: E402
    _fetch_pr_lease_comments_safe,
    gitea_assess_conflict_fix_push,
)

FAKE_AUTH = "Basic dGVzdDp0ZXN0"
AUTHOR_ENV = {
    "GITEA_PROFILE_NAME": "prgs-author",
    "GITEA_ALLOWED_OPERATIONS": "gitea.read,gitea.branch.push,gitea.pr.create",
}

HEAD_BEFORE = "dad1dc8d5108ab01ed83065334116d7425a4471c"
HEAD_AFTER = "3f3d6cb35d0fe225dcb236247f2a2d0ec193fa35"
OPEN_PR = {
    "number": 508,
    "state": "open",
    "head": {"sha": HEAD_AFTER},
}


class TestFetchPrLeaseCommentsSafe(unittest.TestCase):
    @patch("mcp_server.api_request")
    @patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
    def test_pr_lookup_404_returns_structured_failure(self, _auth, mock_api):
        mock_api.side_effect = RuntimeError(
            'HTTP 404: {"message":"issue does not exist","index":508}'
        )
        result = _fetch_pr_lease_comments_safe(
            508, remote="prgs", host=None, org=None, repo=None)
        self.assertFalse(result["success"])
        self.assertEqual(result["comments"], [])
        self.assertTrue(result["reasons"])
        self.assertIn("PR lookup failed", result["reasons"][0])
        self.assertEqual(result["pr_lookup"], "failed")

    @patch("mcp_server.api_request")
    @patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
    def test_comment_fetch_404_after_pr_lookup(self, _auth, mock_api):
        def _api(method, url, auth, *args, **kwargs):
            if "/pulls/" in url:
                return OPEN_PR
            raise RuntimeError(
                'HTTP 404: {"message":"issue does not exist","index":508}'
            )

        mock_api.side_effect = _api
        result = _fetch_pr_lease_comments_safe(
            508, remote="prgs", host=None, org=None, repo=None)
        self.assertFalse(result["success"])
        self.assertIn("comment fetch failed", result["reasons"][0].lower())
        self.assertEqual(result["pr_lookup"], "ok")

    @patch("mcp_server.api_request")
    @patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
    def test_success_returns_comments_and_head_sha(self, _auth, mock_api):
        comment = {"id": 1, "body": "<!-- mcp-conflict-fix-lease:v1 -->"}

        def _api(method, url, auth, *args, **kwargs):
            if "/pulls/" in url:
                return OPEN_PR
            return [comment]

        mock_api.side_effect = _api
        result = _fetch_pr_lease_comments_safe(
            508, remote="prgs", host=None, org=None, repo=None)
        self.assertTrue(result["success"])
        self.assertEqual(result["comments"], [comment])
        self.assertEqual(result["head_sha"], OPEN_PR["head"]["sha"])


class TestAssessConflictFixPushTool(unittest.TestCase):
    @patch("mcp_server._fetch_pr_lease_comments_safe")
    @patch("mcp_server._profile_operation_gate", return_value=None)
    def test_returns_structured_block_when_pr_lookup_fails(
        self, _gate, mock_fetch,
    ):
        mock_fetch.return_value = {
            "success": False,
            "comments": [],
            "reasons": ["PR lookup failed"],
            "pr_lookup": "failed",
            "resolved_repo": "Scaled-Tech-Consulting/Gitea-Tools",
            "remote": "prgs",
            "pr_number": 508,
        }
        with patch.dict(os.environ, AUTHOR_ENV, clear=True):
            result = gitea_assess_conflict_fix_push(
                pr_number=508,
                branch_head_before=HEAD_BEFORE,
                branch_head_after=HEAD_AFTER,
                worktree_path="/proj/branches/fix-pr508",
                push_cwd="/proj/branches/fix-pr508",
                is_fast_forward=True,
                remote="prgs",
            )
        self.assertFalse(result["push_allowed"])
        self.assertTrue(result.get("assessment_failed"))
        self.assertEqual(result["pr_lookup"], "failed")

    @patch("mcp_server._fetch_pr_lease_comments_safe")
    @patch("mcp_server._profile_operation_gate", return_value=None)
    def test_valid_push_assessment_when_pr_and_comments_resolve(
        self, _gate, mock_fetch,
    ):
        mock_fetch.return_value = {
            "success": True,
            "comments": [],
            "reasons": [],
            "pr_lookup": "ok",
            "resolved_repo": "Scaled-Tech-Consulting/Gitea-Tools",
            "remote": "prgs",
            "pr_number": 508,
            "head_sha": HEAD_AFTER,
        }
        with patch.dict(os.environ, AUTHOR_ENV, clear=True):
            result = gitea_assess_conflict_fix_push(
                pr_number=508,
                branch_head_before=HEAD_BEFORE,
                branch_head_after=HEAD_AFTER,
                worktree_path="/proj/branches/fix-pr508",
                push_cwd="/proj/branches/fix-pr508",
                is_fast_forward=True,
                remote="prgs",
            )
        self.assertTrue(result["push_allowed"])
        self.assertEqual(result.get("live_pr_head_sha"), HEAD_AFTER)


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