from __future__ import annotations

import json

import pytest

from src.services.ai_agent_redis_dry_run_gate import (
    load_latest_ai_agent_redis_dry_run_gate,
)


def test_load_latest_ai_agent_redis_dry_run_gate_reads_committed_snapshot():
    data = load_latest_ai_agent_redis_dry_run_gate()

    assert data["schema_version"] == "ai_agent_redis_dry_run_gate_v1"
    assert data["program_status"]["overall_completion_percent"] == 65
    assert data["program_status"]["current_task_id"] == "P2-403C"
    assert data["program_status"]["next_task_id"] == "P2-403D"
    assert data["program_status"]["read_only_mode"] is True
    assert data["program_status"]["runtime_authority"] == "dry_run_contract_only_no_redis_runtime"
    assert data["dry_run_truth"]["redis_connection_allowed"] is False
    assert data["dry_run_truth"]["consumer_group_created"] is False
    assert data["dry_run_truth"]["live_dry_run_event_count"] == 0
    assert data["consumer_group_dry_run_contract"]["fixture_only"] is True
    assert data["consumer_group_dry_run_contract"]["redis_network_call_allowed"] is False
    assert data["handoff_envelope_contract"]["redacted_evidence_required"] is True
    assert data["handoff_envelope_contract"]["idempotency_key_required"] is True
    assert data["ack_dead_letter_replay_contract"]["runtime_replay_allowed"] is False
    assert data["approval_boundaries"]["xadd_allowed"] is False
    assert data["display_redaction_contract"]["raw_payload_display_allowed"] is False
    assert data["rollups"]["dry_run_step_count"] == len(data["dry_run_steps"]) == 5
    assert data["rollups"]["handoff_lane_count"] == len(data["handoff_lanes"]) == 3
    assert data["rollups"]["live_truth_count_total"] == 0


def test_load_latest_ai_agent_redis_dry_run_gate_rejects_redis_runtime(tmp_path):
    snapshot = _snapshot()
    snapshot["approval_boundaries"]["xadd_allowed"] = True
    (tmp_path / "ai_agent_redis_dry_run_gate_2026-06-11.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="approval boundaries"):
        load_latest_ai_agent_redis_dry_run_gate(tmp_path)


def test_load_latest_ai_agent_redis_dry_run_gate_rejects_network_call(tmp_path):
    snapshot = _snapshot()
    snapshot["consumer_group_dry_run_contract"]["redis_network_call_allowed"] = True
    (tmp_path / "ai_agent_redis_dry_run_gate_2026-06-11.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="Redis network calls"):
        load_latest_ai_agent_redis_dry_run_gate(tmp_path)


def test_load_latest_ai_agent_redis_dry_run_gate_rejects_missing_idempotency(tmp_path):
    snapshot = _snapshot()
    snapshot["handoff_envelope_contract"]["required_fields"].remove("idempotency_key")
    (tmp_path / "ai_agent_redis_dry_run_gate_2026-06-11.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="missing required fields"):
        load_latest_ai_agent_redis_dry_run_gate(tmp_path)


def test_load_latest_ai_agent_redis_dry_run_gate_rejects_rollup_mismatch(tmp_path):
    snapshot = _snapshot()
    snapshot["rollups"]["dry_run_step_count"] = 99
    (tmp_path / "ai_agent_redis_dry_run_gate_2026-06-11.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="rollup counts"):
        load_latest_ai_agent_redis_dry_run_gate(tmp_path)


def _snapshot() -> dict:
    return {
        "schema_version": "ai_agent_redis_dry_run_gate_v1",
        "generated_at": "2026-06-11T23:58:00+08:00",
        "program_status": {
            "overall_completion_percent": 65,
            "current_task_id": "P2-403C",
            "next_task_id": "P2-403D",
            "read_only_mode": True,
            "runtime_authority": "dry_run_contract_only_no_redis_runtime",
        },
        "source_refs": ["test"],
        "dry_run_truth": {
            "redis_connection_allowed": False,
            "consumer_group_created": False,
            "xadd_allowed": False,
            "xreadgroup_allowed": False,
            "ack_allowed": False,
            "dead_letter_write_allowed": False,
            "replay_runtime_allowed": False,
            "telegram_send_allowed": False,
            "learning_writeback_allowed": False,
            "live_dry_run_event_count": 0,
            "live_ack_count": 0,
            "live_dead_letter_count": 0,
            "live_replay_count": 0,
        },
        "consumer_group_dry_run_contract": {
            "fixture_only": True,
            "redis_network_call_allowed": False,
            "required_fixture_fields": ["event_id", "idempotency_key"],
        },
        "handoff_envelope_contract": {
            "required_fields": [
                "event_id",
                "trace_id",
                "session_id",
                "incident_id",
                "from_agent",
                "to_agent",
                "handoff_type",
                "redacted_evidence_ref",
                "idempotency_key",
            ],
            "forbidden_fields": ["secret_value", "raw_prompt"],
            "redacted_evidence_required": True,
            "idempotency_key_required": True,
        },
        "ack_dead_letter_replay_contract": {
            "ack_requires_verifier": True,
            "dead_letter_requires_reason": True,
            "replay_requires_idempotency": True,
            "runtime_replay_allowed": False,
        },
        "dry_run_steps": [
            {
                "step_id": "fixture_envelope_validation",
                "display_name": "Fixture",
                "owner_agent": "hermes",
                "status": "contract_ready",
                "operator_signal": "測試。",
                "blocked_runtime_action": "redis_xadd",
            }
        ],
        "handoff_lanes": [
            {
                "lane_id": "diagnosis_to_rule_review",
                "display_name": "診斷",
                "from_agent": "openclaw",
                "to_agent": "hermes",
                "status": "contract_ready",
                "required_evidence": "測試。",
            }
        ],
        "approval_boundaries": {"xadd_allowed": False},
        "display_redaction_contract": {
            "redaction_required": True,
            "raw_payload_display_allowed": False,
            "private_reasoning_display_allowed": False,
            "secret_value_display_allowed": False,
            "forbidden_frontend_content": ["未脫敏 payload"],
        },
        "rollups": {
            "source_ref_count": 1,
            "dry_run_step_count": 1,
            "handoff_lane_count": 1,
            "contract_ready_step_ids": ["fixture_envelope_validation"],
            "approval_required_step_ids": [],
            "blocked_runtime_action_count": 1,
            "required_handoff_field_count": 9,
            "forbidden_field_count": 2,
            "live_truth_count_total": 0,
        },
    }
