"""ORCH-073 FR-2 — pr_already_merged distinguishes code-PR from docs-PR.

Covers TC-05..07. pr_already_merged is now an idempotency-guard: it counts a PR as
"merged" ONLY when it carries the code of THIS feature-branch into main
(merged & head.ref==branch & base.ref=="main"), excluding auto docs-PRs. Gitea HTTP
is mocked; never-raise -> False (INV-1).
"""

import httpx
import pytest

from src import merge_gate

BRANCH = "feature/ORCH-073-x"


class _Resp:
    def __init__(self, status_code, payload=None):
        self.status_code = status_code
        self._payload = payload if payload is not None else []

    def json(self):
        return self._payload


@pytest.fixture(autouse=True)
def _settings(monkeypatch):
    monkeypatch.setattr(merge_gate.settings, "gitea_url", "http://gitea.test")
    monkeypatch.setattr(merge_gate.settings, "gitea_owner", "admin")
    monkeypatch.setattr(merge_gate.settings, "gitea_token", "tok")


# ---------------------------------------------------------------------------
# TC-05: a merged docs-PR (head=docs/*, base=main) is NOT counted as code-merge.
# ---------------------------------------------------------------------------
def test_tc05_merged_docs_pr_not_counted(monkeypatch):
    payload = [
        {"merged": True, "head": {"ref": "docs/ORCH-073-staging-log"}, "base": {"ref": "main"}},
        {"merged": False, "head": {"ref": BRANCH}, "base": {"ref": "main"}},
    ]
    monkeypatch.setattr(httpx, "get", lambda *a, **k: _Resp(200, payload))
    assert merge_gate.pr_already_merged("orchestrator", BRANCH) is False


# ---------------------------------------------------------------------------
# TC-06: a merged code-PR (head==branch, base==main) IS recognised.
# ---------------------------------------------------------------------------
def test_tc06_merged_code_pr_recognised(monkeypatch):
    payload = [
        {"merged": True, "head": {"ref": BRANCH}, "base": {"ref": "main"}},
    ]
    monkeypatch.setattr(httpx, "get", lambda *a, **k: _Resp(200, payload))
    assert merge_gate.pr_already_merged("orchestrator", BRANCH) is True


def test_tc06_merged_code_pr_onto_non_main_base_not_counted(monkeypatch):
    # Right head but a foreign base (not main) must NOT count.
    payload = [
        {"merged": True, "head": {"ref": BRANCH}, "base": {"ref": "develop"}},
    ]
    monkeypatch.setattr(httpx, "get", lambda *a, **k: _Resp(200, payload))
    assert merge_gate.pr_already_merged("orchestrator", BRANCH) is False


# ---------------------------------------------------------------------------
# TC-07: HTTP error / non-200 -> False (never-raise, conservative).
# ---------------------------------------------------------------------------
def test_tc07_non_200_is_false(monkeypatch):
    monkeypatch.setattr(httpx, "get", lambda *a, **k: _Resp(500, []))
    assert merge_gate.pr_already_merged("orchestrator", BRANCH) is False


def test_tc07_http_exception_is_false(monkeypatch):
    def boom(*a, **k):
        raise httpx.ConnectError("gitea unreachable")

    monkeypatch.setattr(httpx, "get", boom)
    assert merge_gate.pr_already_merged("orchestrator", BRANCH) is False
