from __future__ import annotations

import json

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

from src.api.v1.agents import router
from src.services.credential_escrow_evidence_intake_readiness import (
    load_latest_credential_escrow_evidence_intake_readiness,
    validate_credential_escrow_evidence_owner_response,
    validate_credential_escrow_evidence_refs,
)

ESCROW_ITEMS = [
    "restic_repository_password",
    "offsite_provider_credentials",
    "break_glass_admin_credentials",
    "dns_registrar_recovery",
    "oauth_ai_provider_recovery",
]


def test_credential_escrow_evidence_intake_reports_controlled_closeout():
    payload = load_latest_credential_escrow_evidence_intake_readiness()

    assert payload["schema_version"] == "credential_escrow_evidence_intake_readiness_v1"
    assert payload["priority"] == "P0-005"
    assert payload["status"] == "closed_credential_escrow_evidence_refs_controlled_closeout"
    assert payload["safe_next_step"] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
    assert payload["readback"]["safe_next_step"] == payload["safe_next_step"]
    assert payload["readback"]["source_closeout_receipt_ref"] == (
        "docs/operations/"
        "awoooi-credential-escrow-evidence-controlled-closeout-receipt.snapshot.json"
    )
    assert payload["missing_item_count"] == 0
    assert payload["owner_response_accepted_count"] == 1
    assert payload["runtime_gate_count"] == 0
    assert payload["secret_value_collection_allowed"] is False
    assert payload["rollups"]["required_item_count"] == 5
    assert payload["rollups"]["missing_item_count"] == 0
    assert payload["rollups"]["effective_escrow_missing_count"] == 0
    assert payload["rollups"]["accepted_item_count"] == 5
    assert payload["rollups"]["owner_response_received_count"] == 1
    assert payload["rollups"]["owner_response_accepted_count"] == 1
    assert payload["rollups"]["runtime_gate_count"] == 0
    assert payload["rollups"]["credential_marker_write_authorized_count"] == 0
    assert payload["rollups"]["secret_value_collection_allowed"] is False
    assert payload["rollups"]["preflight_status"] == (
        "ready_for_reviewer_acceptance_writeback"
    )
    assert payload["rollups"]["active_gate_present"] is False
    assert payload["rollups"]["controlled_closeout_status"] == (
        "ready_for_p0_005_controlled_closeout"
    )
    assert (
        payload["rollups"]["controlled_closeout_redacted_receipt_writeback_ready_count"]
        == 1
    )
    assert payload["operation_boundaries"]["credential_marker_write_allowed"] is False
    assert payload["operation_boundaries"]["credential_read_allowed"] is False
    assert payload["operation_boundaries"]["secret_plaintext_allowed"] is False
    assert payload["operation_boundaries"]["raw_session_or_sqlite_read_allowed"] is False
    assert payload["rollups"]["blocked_item_ids"] == []
    assert payload["reviewer_readiness"]["status"] == (
        "ready_for_reviewer_acceptance_writeback"
    )
    assert payload["reviewer_readiness"]["projected_effective_escrow_missing_count"] == 0
    assert payload["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
    assert payload["controlled_closeout_receipt"]["status"] == (
        "ready_for_p0_005_controlled_closeout"
    )
    assert all(
        item["contains_secret_value_allowed"] is False
        for item in payload["required_evidence_items"]
    )
    assert all(
        item["controlled_closeout_receipt_accepted"] is True
        for item in payload["required_evidence_items"]
    )
    assert all(
        item["non_secret_evidence_ref"].startswith("review-ticket-20260629-p0-005-")
        for item in payload["required_evidence_items"]
    )


def test_credential_escrow_evidence_intake_exposes_single_preflight_packet():
    payload = load_latest_credential_escrow_evidence_intake_readiness()

    assert payload["single_preflight_intake_ready"] is True
    assert payload["single_preflight_intake_ready_count"] == 1
    assert payload["rollups"]["single_preflight_intake_ready_count"] == 1
    assert payload["owner_response_skeleton_required_item_count"] == 5
    assert payload["owner_response_skeleton_secret_value_collection_allowed"] is False
    assert payload["readback"]["single_preflight_intake_schema_version"] == (
        "credential_escrow_single_preflight_intake_v1"
    )

    intake = payload["single_preflight_intake"]
    assert intake["schema_version"] == "credential_escrow_single_preflight_intake_v1"
    assert intake["workplan_id"] == "P0-005"
    assert intake["status"] == "completed_redacted_non_secret_evidence_refs_receipt_ready"
    assert intake["active_gate"] == "credential_escrow_evidence"
    assert intake["required_item_count"] == 5
    assert intake["required_item_ids"] == ESCROW_ITEMS
    assert [item["item_id"] for item in intake["required_items"]] == ESCROW_ITEMS
    assert all("passwords" in item["rejected_values"] for item in intake["required_items"])
    assert "post-reboot-owner-response-preflight.py" in intake["single_preflight_command"]
    assert (
        "post-reboot-credential-escrow-intake-scorecard.py"
        in intake["scorecard_command"]
    )
    assert "projected_effective_escrow_missing_count=0" in intake["exit_criteria"]
    assert intake["evidence_refs_validation_endpoint"] == (
        "/api/v1/agents/credential-escrow-evidence-intake-readiness/"
        "validate-evidence-refs"
    )
    assert intake["evidence_refs_validation_mode"] == (
        "validate_redacted_non_secret_refs_only_no_persist_no_marker_write"
    )

    owner_packet = intake["owner_packet"]["owner_packets"][0]
    assert owner_packet["packet_id"] == "credential_escrow_evidence"
    assert owner_packet["required_items"] == ESCROW_ITEMS

    response = intake["owner_response_skeleton"]["responses"][0]
    assert response["secret_value_collection_allowed"] is False
    assert response["credential_marker_write_authorized"] is False
    assert response["runtime_action_authorized"] is False
    assert [item["item_id"] for item in response["escrow_items"]] == ESCROW_ITEMS
    assert all(item["contains_secret_value"] is False for item in response["escrow_items"])
    assert intake["operation_boundaries"]["payload_persisted"] is False
    assert intake["operation_boundaries"]["credential_read_performed"] is False
    assert intake["operation_boundaries"]["credential_marker_write_performed"] is False
    assert intake["operation_boundaries"]["runtime_action_performed"] is False


def test_credential_escrow_evidence_intake_endpoint_returns_readiness():
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.get("/api/v1/agents/credential-escrow-evidence-intake-readiness")

    assert response.status_code == 200
    data = response.json()
    assert data["priority"] == "P0-005"
    assert data["safe_next_step"] == "continue_to_p0_006_source_to_runtime_drift_cleanup"
    assert data["missing_item_count"] == 0
    assert data["owner_response_accepted_count"] == 1
    assert data["runtime_gate_count"] == 0
    assert data["secret_value_collection_allowed"] is False
    assert data["rollups"]["missing_item_count"] == 0
    assert data["rollups"]["effective_escrow_missing_count"] == 0
    assert data["rollups"]["accepted_item_count"] == 5
    assert data["rollups"]["controlled_closeout_status"] == (
        "ready_for_p0_005_controlled_closeout"
    )
    assert data["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
    assert data["single_preflight_intake"]["required_item_ids"] == ESCROW_ITEMS
    assert data["single_preflight_intake"]["operation_boundaries"][
        "secret_value_collection_allowed"
    ] is False
    assert data["operation_boundaries"]["restore_execution_allowed"] is False
    assert data["operation_boundaries"]["workflow_trigger_allowed"] is False


def test_credential_escrow_evidence_owner_response_validator_accepts_redacted_refs_only():
    payload = validate_credential_escrow_evidence_owner_response(
        _valid_redacted_owner_response(),
        readiness={
            "status": "blocked_waiting_non_secret_credential_escrow_evidence",
            "rollups": {"effective_escrow_missing_count": 5},
        },
    )

    assert payload["schema_version"] == "credential_escrow_evidence_owner_response_validation_v1"
    assert payload["status"] == "accepted_for_independent_reviewer_readiness_only"
    assert payload["result"]["owner_response_received_count"] == 1
    assert payload["result"]["owner_response_accepted_count"] == 1
    assert payload["result"]["required_item_count"] == 5
    assert payload["result"]["accepted_item_count"] == 5
    assert payload["result"]["current_effective_escrow_missing_count"] == 5
    assert payload["result"]["projected_effective_escrow_missing_count"] == 0
    assert payload["result"]["runtime_gate_count"] == 0
    assert payload["result"]["credential_marker_write_authorized_count"] == 0
    assert payload["result"]["secret_value_collection_allowed"] is False
    assert payload["operation_boundaries"]["payload_persisted"] is False
    assert payload["operation_boundaries"]["credential_read_performed"] is False
    assert payload["operation_boundaries"]["credential_marker_write_performed"] is False
    assert payload["operation_boundaries"]["runtime_action_performed"] is False
    assert (
        payload["reviewer_readiness"]["status"]
        == "ready_for_reviewer_acceptance_writeback"
    )
    assert payload["reviewer_readiness"]["projected_effective_escrow_missing_count"] == 0
    assert payload["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
    assert payload["reviewer_readiness"]["credential_marker_write_authorized_count"] == 0
    assert payload["reviewer_readiness"]["secret_value_collection_allowed"] is False


def test_credential_escrow_evidence_owner_response_validator_quarantines_secret_payload():
    response = _valid_redacted_owner_response()
    response["responses"][0]["redacted_evidence_refs"] = [
        "password=not-allowed-even-in-tests"
    ]

    payload = validate_credential_escrow_evidence_owner_response(
        response,
        readiness={"status": "blocked_waiting_non_secret_credential_escrow_evidence"},
    )

    assert payload["status"] == "quarantined_sensitive_payload"
    assert payload["result"]["owner_response_accepted_count"] == 0
    assert payload["result"]["sensitive_payload_hit_count"] == 1
    assert payload["operation_boundaries"]["payload_persisted"] is False


def test_credential_escrow_evidence_owner_response_validator_rejects_runtime_or_marker_action():
    response = _valid_redacted_owner_response()
    response["responses"][0]["runtime_action_authorized"] = True
    response["responses"][0]["credential_marker_write_authorized"] = True

    payload = validate_credential_escrow_evidence_owner_response(
        response,
        readiness={"status": "blocked_waiting_non_secret_credential_escrow_evidence"},
    )

    assert payload["status"] == "rejected_runtime_or_marker_action"
    assert payload["result"]["owner_response_accepted_count"] == 0
    assert payload["result"]["forbidden_true_field_count"] == 2
    assert payload["operation_boundaries"]["credential_marker_write_performed"] is False


def test_credential_escrow_evidence_refs_validator_accepts_simplified_refs():
    payload = validate_credential_escrow_evidence_refs(
        _valid_evidence_refs_submission(),
        readiness={
            "status": "blocked_waiting_non_secret_credential_escrow_evidence",
            "rollups": {"effective_escrow_missing_count": 5},
        },
    )

    assert payload["schema_version"] == "credential_escrow_evidence_refs_validation_v1"
    assert payload["status"] == "accepted_for_independent_reviewer_readiness_only"
    assert payload["scope"] == "credential_escrow_evidence_refs_intake"
    assert payload["result"]["simplified_evidence_ref_submission_count"] == 5
    assert payload["result"]["accepted_item_count"] == 5
    assert payload["result"]["missing_required_item_ids"] == []
    assert payload["result"]["projected_effective_escrow_missing_count"] == 0
    assert payload["result"]["credential_marker_write_authorized_count"] == 0
    assert payload["result"]["payload_persisted"] is False
    assert payload["operation_boundaries"]["payload_persisted"] is False
    assert payload["operation_boundaries"]["credential_marker_write_performed"] is False
    assert payload["operation_boundaries"]["runtime_action_performed"] is False
    assert (
        payload["source_owner_response_validation"]["status"]
        == "accepted_for_independent_reviewer_readiness_only"
    )
    assert payload["safe_next_step"] == (
        "independent_reviewer_acceptance_then_marker_dry_run"
    )


def test_credential_escrow_evidence_refs_validator_quarantines_secret_ref():
    submission = _valid_evidence_refs_submission()
    submission["evidence_refs"]["restic_repository_password"] = (
        "password=not-allowed"
    )

    payload = validate_credential_escrow_evidence_refs(
        submission,
        readiness={
            "status": "blocked_waiting_non_secret_credential_escrow_evidence",
            "rollups": {"effective_escrow_missing_count": 5},
        },
    )

    assert payload["status"] == "quarantined_sensitive_payload"
    assert payload["result"]["owner_response_accepted_count"] == 0
    assert payload["result"]["source_sensitive_payload_hit_count"] == 1
    assert payload["operation_boundaries"]["payload_persisted"] is False


def test_credential_escrow_evidence_refs_endpoint_validates_without_persisting():
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.post(
        "/api/v1/agents/credential-escrow-evidence-intake-readiness/"
        "validate-evidence-refs",
        json=_valid_evidence_refs_submission(),
    )

    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "accepted_for_independent_reviewer_readiness_only"
    assert data["result"]["projected_effective_escrow_missing_count"] == 0
    assert data["result"]["payload_persisted"] is False
    assert data["operation_boundaries"]["secret_plaintext_read"] is False
    assert data["operation_boundaries"]["credential_marker_write_performed"] is False


def test_credential_escrow_evidence_owner_response_endpoint_validates_without_persisting():
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.post(
        "/api/v1/agents/credential-escrow-evidence-intake-readiness/validate-owner-response",
        json=_valid_redacted_owner_response(),
    )

    assert response.status_code == 200
    data = response.json()
    assert data["status"] == "accepted_for_independent_reviewer_readiness_only"
    assert data["result"]["owner_response_accepted_count"] == 1
    assert data["result"]["projected_effective_escrow_missing_count"] == 0
    assert (
        data["reviewer_readiness"]["status"]
        == "ready_for_reviewer_acceptance_writeback"
    )
    assert data["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1
    assert data["operation_boundaries"]["payload_persisted"] is False
    assert data["operation_boundaries"]["secret_plaintext_read"] is False
    assert data["operation_boundaries"]["host_or_k8s_write_performed"] is False


def test_credential_escrow_evidence_intake_rejects_secret_collection(tmp_path):
    security_dir = tmp_path / "security"
    security_dir.mkdir()
    owner_request = {
        "scope": "credential_escrow_evidence_owner_request",
        "generated_at": "2026-06-29T00:00:00+08:00",
        "missing_items": [
            {
                "item": "restic_repository_password",
                "status": "missing",
                "allowed_evidence_id_types": ["vault_item_id"],
            }
        ],
        "forbidden_values": ["password"],
        "gates": {
            "secret_value_collection_authorized": True,
            "marker_write_completed": False,
        },
    }
    (security_dir / "credential-escrow-evidence-owner-request.snapshot.json").write_text(
        json.dumps(owner_request),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="secret value collection"):
        load_latest_credential_escrow_evidence_intake_readiness(
            security_dir,
            backup_dr_readiness_matrix=_backup_matrix(),
        )


def test_credential_escrow_evidence_intake_rejects_marker_write_authorization(tmp_path):
    security_dir = tmp_path / "security"
    security_dir.mkdir()
    owner_request = {
        "scope": "credential_escrow_evidence_owner_request",
        "generated_at": "2026-06-29T00:00:00+08:00",
        "missing_items": [
            {
                "item": "restic_repository_password",
                "status": "missing",
                "allowed_evidence_id_types": ["vault_item_id"],
            }
        ],
        "forbidden_values": ["password"],
        "gates": {
            "secret_value_collection_authorized": False,
            "marker_write_completed": False,
        },
    }
    (security_dir / "credential-escrow-evidence-owner-request.snapshot.json").write_text(
        json.dumps(owner_request),
        encoding="utf-8",
    )
    matrix = _backup_matrix()
    matrix["rollups"]["credential_marker_write_authorized_count"] = 1

    with pytest.raises(ValueError, match="credential marker write"):
        load_latest_credential_escrow_evidence_intake_readiness(
            security_dir,
            backup_dr_readiness_matrix=matrix,
        )


def _backup_matrix() -> dict:
    return {
        "rollups": {
            "credential_escrow_intake_status": (
                "blocked_waiting_non_secret_credential_escrow_evidence"
            ),
            "credential_escrow_effective_missing_count": 1,
            "credential_escrow_owner_response_received_count": 0,
            "credential_escrow_owner_response_accepted_count": 0,
            "credential_escrow_runtime_gate_count": 0,
            "credential_marker_write_authorized_count": 0,
            "credential_escrow_secret_value_collection_allowed": False,
            "credential_escrow_forbidden_true_field_count": 0,
        }
    }


def _valid_redacted_owner_response() -> dict:
    return {
        "schema_version": "awoooi_post_reboot_next_gate_owner_response_v1",
        "responses": [
            {
                "gate_id": "credential_escrow_evidence",
                "owner_role": "backup_dr_owner",
                "owner_team": "platform_security",
                "decision": "accepted",
                "decision_reason": "reviewed redacted non-secret evidence refs only",
                "affected_scope": "P0-005 DR credential escrow evidence",
                "redacted_evidence_refs": ["review-ticket-20260629-p0-005"],
                "followup_owner": "backup_dr_owner",
                "runtime_action_requested": False,
                "runtime_action_authorized": False,
                "host_write_requested": False,
                "host_write_authorized": False,
                "secret_value_included": False,
                "secret_value_collection_allowed": False,
                "credential_marker_write_requested": False,
                "credential_marker_write_authorized": False,
                "escrow_items": [
                    {
                        "item_id": item_id,
                        "non_secret_evidence_ref": f"review-ticket-20260629-p0-005-{index}",
                        "recovery_owner": "backup_dr_owner",
                        "reviewer": "security_reviewer",
                        "last_reviewed_at": "2026-06-29",
                        "contains_secret_value": False,
                    }
                    for index, item_id in enumerate(ESCROW_ITEMS)
                ],
            }
        ],
    }


def _valid_evidence_refs_submission() -> dict:
    return {
        "owner_role": "backup_dr_owner",
        "owner_team": "platform_security",
        "reviewer": "security_reviewer",
        "last_reviewed_at": "2026-06-29",
        "followup_owner": "backup_dr_owner",
        "redacted_evidence_refs": ["review-ticket-20260629-p0-005"],
        "evidence_refs": {
            item_id: f"review-ticket-20260629-p0-005-{index}"
            for index, item_id in enumerate(ESCROW_ITEMS)
        },
    }
