"""ORCH-026 Level A (TC-A01): proactive pre-merge rebase.

check_branch_mergeable must ALWAYS rebase the task branch onto the current
origin/main under the held merge-lease when ``premerge_rebase_always`` is on —
even when ``branch_is_behind_main`` would short-circuit (no conflict, formally
not behind). With the flag OFF the ORCH-043 short-circuit is restored 1:1.

These are pure unit tests: every merge_gate primitive is monkeypatched, so no
git/network is touched — we assert the CONTROL FLOW (was auto_rebase_onto_main
called?) and the verdict.
"""
import os
import tempfile

import pytest

os.environ.setdefault("ORCH_DB_PATH", os.path.join(tempfile.gettempdir(), "test_orch026_premerge.db"))
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")
os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")

from src import merge_gate  # noqa: E402
from src.qg import checks  # noqa: E402


@pytest.fixture
def patched_gate(monkeypatch):
    """Patch merge_gate primitives; record whether auto_rebase ran."""
    calls = {"rebase": 0, "retest": 0, "released": 0, "behind_checked": 0}

    monkeypatch.setattr(checks.settings, "merge_gate_enabled", True, raising=False)
    monkeypatch.setattr(checks.settings, "merge_gate_repos", "", raising=False)

    monkeypatch.setattr(merge_gate, "acquire_merge_lease",
                        lambda *a, **k: (True, "lease acquired"), raising=False)

    def _behind(repo, branch):
        calls["behind_checked"] += 1
        return False  # NOT behind -> ORCH-043 would short-circuit

    def _rebase(repo, branch):
        calls["rebase"] += 1
        return True, "rebased (noop)"

    def _retest(repo, branch):
        calls["retest"] += 1
        return True, "green"

    def _release(repo, branch=None):
        calls["released"] += 1

    monkeypatch.setattr(merge_gate, "branch_is_behind_main", _behind, raising=False)
    monkeypatch.setattr(merge_gate, "auto_rebase_onto_main", _rebase, raising=False)
    monkeypatch.setattr(merge_gate, "retest_branch", _retest, raising=False)
    monkeypatch.setattr(merge_gate, "release_merge_lease", _release, raising=False)
    return calls


def test_always_rebases_even_when_not_behind(patched_gate, monkeypatch):
    """premerge_rebase_always=True -> auto_rebase_onto_main ALWAYS called (AC-A2)."""
    monkeypatch.setattr(checks.settings, "premerge_rebase_always", True, raising=False)
    ok, reason = checks.check_branch_mergeable("orchestrator", "ORCH-026", "feature/x")
    assert ok is True
    assert patched_gate["rebase"] == 1, "rebase must run even when not behind"
    assert patched_gate["retest"] == 1, "re-test must run after the proactive rebase"


def test_flag_off_short_circuits_like_orch043(patched_gate, monkeypatch):
    """premerge_rebase_always=False -> not-behind short-circuit, no rebase (AC-A7)."""
    monkeypatch.setattr(checks.settings, "premerge_rebase_always", False, raising=False)
    ok, reason = checks.check_branch_mergeable("orchestrator", "ORCH-026", "feature/x")
    assert ok is True
    assert reason == "branch up-to-date with main"
    assert patched_gate["rebase"] == 0, "must NOT rebase when not behind and flag off"


def test_disabled_gate_is_noop(monkeypatch):
    """merge_gate_enabled=False -> pass-through, no lease/rebase at all (AC-G2)."""
    monkeypatch.setattr(checks.settings, "merge_gate_enabled", False, raising=False)
    monkeypatch.setattr(checks.settings, "premerge_rebase_always", True, raising=False)
    ok, reason = checks.check_branch_mergeable("orchestrator", "ORCH-026", "feature/x")
    assert ok is True
    assert "disabled" in reason
