"""consult.py codex effort-provenance wiring.

The Opus x Codex pairing dialogue (2026-06-03) caught a "caused-action gap": the
codex consult engine ran at an unmeasured ambient effort because nothing wired
model_reasoning_effort into the `codex exec` argv. These tests guard the fix:
codex consults must (1) default to high, (2) pass low/medium/high through, and
(3) clamp claude-only xhigh/max down to codex's top level "high" — and the flag
must actually appear in the command line.
"""
import subprocess
from pathlib import Path

from recoil.pipeline.tools.consult import (
    _resolve_codex_effort,
    run_codex_consultation,
)


def test_resolve_codex_effort_mapping():
    assert _resolve_codex_effort(None) == ("high", False)        # default
    assert _resolve_codex_effort("medium") == ("medium", False)  # passthrough
    assert _resolve_codex_effort("high") == ("high", False)
    assert _resolve_codex_effort("minimal") == ("minimal", False)
    assert _resolve_codex_effort("xhigh") == ("high", True)      # clamped
    assert _resolve_codex_effort("max") == ("high", True)        # clamped


def _capture_codex_cmd(monkeypatch, effort, output_schema=None, cwd=None):
    """Run run_codex_consultation with subprocess mocked; return the argv it built."""
    captured = {}

    def fake_run(cmd, **kwargs):
        captured["cmd"] = cmd
        # Write the -o output file so the function returns instead of raising.
        # Must be a non-degenerate payload: >=200 chars and no VERIFICATION footer
        # so _is_degenerate_response returns False.
        oi = cmd.index("-o")
        Path(cmd[oi + 1]).write_text("A" * 300)

        class _Proc:
            returncode = 0
            stderr = ""

        return _Proc()

    monkeypatch.setattr(subprocess, "run", fake_run)
    out = run_codex_consultation(
        "ctx", "prompt", effort=effort, output_schema=output_schema, cwd=cwd
    )
    assert out == "A" * 300
    return captured["cmd"]


def test_cwd_none_defaults_to_repo_root(monkeypatch):
    from recoil.pipeline.tools.consult import REPO_ROOT_LOCAL

    cmd = _capture_codex_cmd(monkeypatch, None)
    assert cmd[cmd.index("-C") + 1] == str(REPO_ROOT_LOCAL)


def test_cwd_override_threads_to_dash_C(monkeypatch):
    cmd = _capture_codex_cmd(monkeypatch, None, cwd="/some/other/repo")
    assert cmd[cmd.index("-C") + 1] == "/some/other/repo"


def test_codex_cmd_includes_effort_flag_default_high(monkeypatch):
    cmd = _capture_codex_cmd(monkeypatch, None)
    assert "-c" in cmd
    assert "model_reasoning_effort=high" in cmd


def test_codex_cmd_effort_passthrough(monkeypatch):
    assert "model_reasoning_effort=medium" in _capture_codex_cmd(monkeypatch, "medium")


def test_codex_cmd_effort_clamps_xhigh(monkeypatch):
    # xhigh has no codex equivalent above "high" -> clamps to high
    assert "model_reasoning_effort=high" in _capture_codex_cmd(monkeypatch, "xhigh")


def test_output_schema_none_omits_flag(monkeypatch):
    cmd = _capture_codex_cmd(monkeypatch, None, output_schema=None)
    assert "--output-schema" not in cmd


def test_output_schema_path_adds_flag(monkeypatch, tmp_path):
    schema = tmp_path / "s.json"
    schema.write_text("{}")
    cmd = _capture_codex_cmd(monkeypatch, None, output_schema=schema)
    assert "--output-schema" in cmd
    assert cmd[cmd.index("--output-schema") + 1] == str(schema)


def test_output_schema_str_adds_flag(monkeypatch):
    cmd = _capture_codex_cmd(monkeypatch, None, output_schema="/tmp/x.json")
    assert "--output-schema" in cmd
    assert cmd[cmd.index("--output-schema") + 1] == "/tmp/x.json"
