"""Tests for gitea_list_prs pagination metadata (#340)."""
import os
import sys
import unittest
from unittest.mock import patch

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

import gitea_auth  # noqa: E402
from mcp_server import gitea_list_prs  # noqa: E402
from review_proofs import assess_list_prs_pagination_proof  # noqa: E402

FAKE_AUTH = "Basic dGVzdDp0ZXN0"
URL = "https://gitea.example.com/api/v1/repos/o/r/pulls?state=open"

SAMPLE_PR = {
    "number": 1,
    "title": "PR 1",
    "state": "open",
    "head": {"ref": "branch1"},
    "base": {"ref": "master"},
    "mergeable": True,
    "updated_at": "2026-07-05T12:00:00Z",
}


class TestApiFetchPage(unittest.TestCase):
    @patch("gitea_auth.api_request")
    def test_final_page_metadata(self, mock_req):
        mock_req.return_value = [SAMPLE_PR]
        items, meta = gitea_auth.api_fetch_page(URL, FAKE_AUTH, page=1, limit=50)
        self.assertEqual(len(items), 1)
        self.assertFalse(meta["has_more"])
        self.assertTrue(meta["is_final_page"])
        self.assertIsNone(meta["next_page"])

    @patch("gitea_auth.api_request")
    def test_full_page_has_more(self, mock_req):
        mock_req.return_value = [{"id": i} for i in range(2)]
        items, meta = gitea_auth.api_fetch_page(URL, FAKE_AUTH, page=1, limit=2)
        self.assertEqual(len(items), 2)
        self.assertTrue(meta["has_more"])
        self.assertFalse(meta["is_final_page"])
        self.assertEqual(meta["next_page"], 2)


class TestGiteaListPrsPagination(unittest.TestCase):
    @patch("mcp_server.api_fetch_page")
    @patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
    def test_explicit_page_returns_has_more(self, _auth, mock_fetch):
        mock_fetch.return_value = (
            [SAMPLE_PR],
            {
                "page": 1,
                "per_page": 50,
                "returned_count": 1,
                "has_more": False,
                "next_page": None,
                "is_final_page": True,
            },
        )
        with patch.dict(os.environ, {}, clear=True):
            result = gitea_list_prs(page=1, per_page=50)
        self.assertEqual(len(result["prs"]), 1)
        self.assertFalse(result["pagination"]["inventory_complete"])
        self.assertTrue(result["pagination"]["is_final_page"])

    @patch("mcp_server.api_fetch_page")
    @patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
    def test_multi_page_fetch_all_marks_inventory_complete(self, _auth, mock_fetch):
        mock_fetch.side_effect = [
            (
                [dict(SAMPLE_PR, number=i) for i in (1, 2)],
                {
                    "page": 1,
                    "per_page": 2,
                    "returned_count": 2,
                    "has_more": True,
                    "next_page": 2,
                    "is_final_page": False,
                },
            ),
            (
                [dict(SAMPLE_PR, number=3)],
                {
                    "page": 2,
                    "per_page": 2,
                    "returned_count": 1,
                    "has_more": False,
                    "next_page": None,
                    "is_final_page": True,
                },
            ),
        ]
        with patch.dict(os.environ, {}, clear=True):
            result = gitea_list_prs(per_page=2)
        self.assertEqual([p["number"] for p in result["prs"]], [1, 2, 3])
        self.assertTrue(result["pagination"]["inventory_complete"])
        self.assertEqual(result["pagination"]["pages_fetched"], 2)
        self.assertEqual(result["pagination"]["total_count"], 3)


class TestListPrsPaginationProof(unittest.TestCase):
    def test_wrapped_final_page_passes_completeness_claim(self):
        response = {
            "prs": [],
            "pagination": {
                "page": 1,
                "per_page": 50,
                "returned_count": 0,
                "has_more": False,
                "next_page": None,
                "is_final_page": True,
                "inventory_complete": True,
                "pages_fetched": 1,
                "total_count": 0,
            },
        }
        result = assess_list_prs_pagination_proof(
            response, inventory_complete_claimed=True
        )
        self.assertTrue(result["proven"])

    def test_bare_list_blocks_completeness_claim(self):
        result = assess_list_prs_pagination_proof(
            [{"number": 1}], inventory_complete_claimed=True
        )
        self.assertFalse(result["proven"])
        self.assertIn("pagination metadata", " ".join(result["reasons"]))

    def test_single_page_without_complete_blocks_claim(self):
        response = {
            "prs": [{"number": 1}],
            "pagination": {
                "page": 1,
                "per_page": 50,
                "returned_count": 1,
                "has_more": True,
                "next_page": 2,
                "is_final_page": False,
                "inventory_complete": False,
                "pages_fetched": 1,
                "total_count": None,
            },
        }
        result = assess_list_prs_pagination_proof(
            response, inventory_complete_claimed=True
        )
        self.assertFalse(result["proven"])


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