from __future__ import annotations

import json
import subprocess
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parents[3]
SCRIPT = ROOT / "scripts" / "reboot-recovery" / "dr-escrow-evidence-checklist.py"
PREFLIGHT_SCRIPT = ROOT / "scripts" / "reboot-recovery" / "post-reboot-owner-response-preflight.py"
APPLY_RECEIPT_SCRIPT = (
    ROOT
    / "scripts"
    / "reboot-recovery"
    / "apply-credential-escrow-closeout-receipt-to-110.sh"
)

ITEMS = {
    "restic_repository_password",
    "offsite_provider_credentials",
    "break_glass_admin_credentials",
    "dns_registrar_recovery",
    "oauth_ai_provider_recovery",
}


def load_checklist() -> dict:
    result = subprocess.run(
        [sys.executable, str(SCRIPT)],
        text=True,
        capture_output=True,
        check=True,
    )
    return json.loads(result.stdout)


def run_preflight(tmp_path: Path, owner_packet: dict, response: dict) -> dict:
    packet_path = tmp_path / "owner-packet.json"
    response_path = tmp_path / "owner-response.json"
    packet_path.write_text(json.dumps(owner_packet, indent=2) + "\n", encoding="utf-8")
    response_path.write_text(json.dumps(response, indent=2) + "\n", encoding="utf-8")
    result = subprocess.run(
        [
            sys.executable,
            str(PREFLIGHT_SCRIPT),
            "--owner-packet-file",
            str(packet_path),
            "--response-file",
            str(response_path),
            "--json",
        ],
        text=True,
        capture_output=True,
        check=True,
    )
    return json.loads(result.stdout)


def test_checklist_is_single_p0_005_intake_packet() -> None:
    payload = load_checklist()

    assert payload["schema_version"] == "awoooi_dr_escrow_evidence_checklist_v1"
    assert payload["workplan_id"] == "P0-005"
    assert payload["active_gate"] == "credential_escrow_evidence"
    assert payload["required_item_count"] == 5
    assert {item["item_id"] for item in payload["required_items"]} == ITEMS
    assert payload["owner_packet"]["source"]["next_required_gates"] == [
        "credential_escrow_evidence"
    ]
    assert len(payload["owner_packet"]["owner_packets"]) == 1
    assert len(payload["owner_response_skeleton"]["responses"]) == 1


def test_checklist_never_authorizes_runtime_or_secret_collection() -> None:
    payload = load_checklist()
    response = payload["owner_response_skeleton"]["responses"][0]

    forbidden_true_fields = [
        "runtime_action_requested",
        "runtime_action_authorized",
        "host_write_requested",
        "host_write_authorized",
        "secret_value_included",
        "secret_value_collection_allowed",
        "credential_marker_write_requested",
        "credential_marker_write_authorized",
    ]
    for field in forbidden_true_fields:
        assert response[field] is False
    for item in response["escrow_items"]:
        assert item["contains_secret_value"] is False


def test_checklist_outputs_marker_dry_run_commands_only() -> None:
    payload = load_checklist()

    for item in payload["required_items"]:
        command = item["marker_dry_run_command"]
        assert "--dry-run" in command
        assert "--item " + item["item_id"] in command
        assert " --evidence-id <NON_SECRET_REF_FOR_" in command
        assert "--token" not in command
        assert "password=" not in command.lower()


def test_apply_closeout_receipt_script_is_no_secret_controlled_marker_write() -> None:
    text = APPLY_RECEIPT_SCRIPT.read_text(encoding="utf-8")

    assert "--dry-run" in text
    assert "--apply" in text
    assert "--rollback" in text
    assert "awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json" in text
    assert "contains_secret_value" in text
    assert "secret_value_collection_allowed" in text
    assert "mark-credential-escrow-verified.sh" in text
    assert "ROLLBACK_DIR=" in text
    assert "-n" in text
    assert "cat ~/.ssh" not in text
    assert "cat .env" not in text
    assert "auth.json" not in text
    assert ".sqlite" not in text
    assert "cat ~/.codex/sessions" not in text


def test_unfilled_skeleton_fails_closed_against_preflight(tmp_path: Path) -> None:
    payload = load_checklist()

    preflight = run_preflight(
        tmp_path,
        payload["owner_packet"],
        payload["owner_response_skeleton"],
    )

    assert preflight["status"] == "blocked_waiting_owner_response_content"
    assert preflight["owner_response_received_count"] == 0
    assert preflight["owner_response_accepted_count"] == 0
    assert preflight["runtime_action_authorized"] is False
    assert preflight["secret_value_collection_allowed"] is False
    blockers = "\n".join(preflight["blockers"])
    assert "credential_escrow_evidence.owner_role_missing" in blockers
    assert "credential_escrow_evidence.restic_repository_password.non_secret_evidence_ref_missing" in blockers


def test_angle_bracket_placeholder_refs_cannot_be_accepted(tmp_path: Path) -> None:
    payload = load_checklist()
    response = payload["owner_response_skeleton"]
    item = response["responses"][0]
    item.update(
        {
            "owner_role": "backup_dr_owner",
            "owner_team": "platform_security",
            "decision": "accepted",
            "decision_reason": "reviewed redacted evidence refs only",
            "redacted_evidence_refs": ["review-ticket-20260629"],
            "followup_owner": "backup_dr_owner",
        }
    )
    for escrow_item in item["escrow_items"]:
        item_id = escrow_item["item_id"]
        escrow_item.update(
            {
                "non_secret_evidence_ref": f"<NON_SECRET_REF_FOR_{item_id}>",
                "recovery_owner": "backup_dr_owner",
                "reviewer": "security_reviewer",
                "last_reviewed_at": "2026-06-29",
            }
        )

    preflight = run_preflight(tmp_path, payload["owner_packet"], response)

    assert preflight["status"] == "blocked_waiting_owner_response_content"
    assert preflight["owner_response_received_count"] == 0
    assert preflight["owner_response_accepted_count"] == 0
    blockers = "\n".join(preflight["blockers"])
    for item_id in ITEMS:
        assert f"credential_escrow_evidence.{item_id}.non_secret_evidence_ref_missing" in blockers
