from __future__ import annotations

from fastapi import FastAPI
from fastapi.testclient import TestClient

from src.api.v1.agents import router


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

    response = client.get("/api/v1/agents/github-target-private-backup-evidence-gate")

    assert response.status_code == 200
    data = response.json()
    assert data["schema_version"] == "github_target_private_backup_evidence_gate_v1"
    assert data["mode"] == "owner_authorized_controlled_execution_no_secret_plaintext"
    assert data["status"] == "owner_authorized_controlled_execution_preflight_ready"
    assert data["summary"]["approval_required_target_count"] == 9
    assert data["summary"]["github_connector_readback_count"] == 9
    assert data["summary"]["github_connector_private_visibility_count"] == 4
    assert data["summary"]["github_connector_not_found_or_inaccessible_count"] == 5
    assert data["summary"]["github_missing_target_resolution_count"] == 5
    assert data["summary"]["github_missing_target_gitea_source_candidate_count"] == 3
    assert data["summary"]["github_missing_target_create_private_repo_ready_count"] == 0
    assert data["summary"]["github_missing_target_refs_sync_ready_count"] == 0
    assert (
        data["summary"]["github_missing_target_create_private_repo_authorized_count"]
        == 5
    )
    assert data["summary"]["github_missing_target_refs_sync_authorized_count"] == 5
    assert data["summary"]["github_controlled_execution_preflight_ready"] is False
    assert data["summary"]["github_write_channel_ready"] is False
    assert data["summary"]["github_create_repo_channel_ready"] is False
    assert data["summary"]["github_refs_sync_channel_ready"] is False
    assert data["summary"]["github_missing_target_controlled_apply_ready_count"] == 0
    assert data["summary"]["github_missing_target_blocked_preflight_count"] == 5
    assert data["summary"]["github_missing_target_github_404_count"] == 0
    assert data["summary"]["github_account_status"] == "suspended"
    assert data["summary"]["github_account_suspended"] is True
    assert data["summary"]["github_api_forbidden_count"] == 6
    assert data["summary"]["private_backup_verified_count"] == 4
    assert data["summary"]["private_visibility_verified_count"] == 4
    assert data["summary"]["safe_credential_evidence_intake_ready"] is True
    assert data["summary"]["safe_credential_required_redacted_evidence_ref_count"] == 9
    assert data["summary"]["safe_credential_evidence_ref_rule_count"] == 5
    assert data["summary"]["safe_credential_redaction_example_count"] == 5
    assert data["summary"]["safe_credential_forbidden_payload_count"] == 15
    assert data["summary"]["safe_credential_quarantine_lane_count"] == 1
    assert data["summary"]["safe_credential_raw_payload_storage_allowed"] is False
    assert data["summary"]["safe_credential_reviewer_validation_ready"] is True
    assert (
        data["summary"]["safe_credential_reviewer_validation_required_field_count"] == 7
    )
    assert data["summary"]["safe_credential_reviewer_validation_passed_count"] == 0
    assert data["summary"]["owner_response_request_ready"] is True
    assert data["summary"]["owner_response_required_response_item_count"] == 9
    assert data["summary"]["owner_response_requested_template_count"] == 9
    assert data["summary"]["owner_response_template_count"] == 9
    assert data["summary"]["owner_response_collection_check_count"] == 6
    assert data["summary"]["owner_response_intake_preflight_check_count"] == 6
    assert data["summary"]["owner_response_request_execution_authorized"] is False
    assert data["summary"]["owner_execution_authorization_received_count"] == 1
    assert data["summary"]["owner_execution_authorized_target_count"] == 9
    assert data["summary"]["execution_ready_count"] == 9
    assert data["summary"]["blocked_target_count"] == 0
    assert data["summary"]["public_repo_allowed"] is False
    assert data["summary"]["repo_creation_authorized"] is True
    assert data["summary"]["visibility_change_authorized"] is True
    assert data["summary"]["refs_sync_authorized"] is True
    assert data["summary"]["workflow_trigger_authorized"] is True
    assert data["summary"]["secret_value_collection_allowed"] is False
    assert data["operation_boundaries"]["read_only_api_allowed"] is True
    assert data["operation_boundaries"]["github_api_write_allowed"] is True
    assert data["operation_boundaries"]["repo_creation_allowed"] is True
    assert data["operation_boundaries"]["visibility_change_allowed"] is True
    assert data["operation_boundaries"]["refs_sync_allowed"] is True
    assert data["operation_boundaries"]["workflow_trigger_allowed"] is True
    assert data["operation_boundaries"]["github_write_channel_ready"] is False
    assert data["operation_boundaries"]["controlled_apply_allowed"] is False
    assert data["operation_boundaries"]["private_clone_url_collection_allowed"] is False
    intake = data["owner_response_intake_readiness"]
    assert (
        intake["status"]
        == "ready_to_collect_read_only_owner_response_not_authorization"
    )
    assert intake["request_ready"] is True
    assert intake["requested_template_count"] == 9
    assert intake["forbidden_payload_count"] == 15
    assert intake["execution_authorized"] is False
    assert intake["not_approval"] is True
    safe_credential_intake = data["safe_credential_evidence_intake_readiness"]
    assert (
        safe_credential_intake["status"]
        == "ready_to_collect_redacted_evidence_refs_not_credentials"
    )
    assert safe_credential_intake["intake_ready"] is True
    assert safe_credential_intake["required_target_count"] == 9
    assert safe_credential_intake["required_redacted_evidence_ref_count"] == 9
    assert safe_credential_intake["evidence_ref_rule_count"] == 5
    assert safe_credential_intake["redaction_example_count"] == 5
    assert safe_credential_intake["forbidden_payload_count"] == 15
    assert safe_credential_intake["quarantine_lane_count"] == 1
    assert safe_credential_intake["stored_raw_payload_allowed"] is False
    assert safe_credential_intake["private_clone_url_collection_allowed"] is False
    assert safe_credential_intake["secret_value_collection_allowed"] is False
    assert safe_credential_intake["execution_authorized"] is False
    assert safe_credential_intake["not_approval"] is True
    assert safe_credential_intake["reviewer_validation_ready"] is True
    assert (
        safe_credential_intake["reviewer_validation_endpoint"]
        == "/api/v1/agents/github-target-safe-credential-evidence-reviewer-validation/validate-redacted-refs"
    )
    assert data["targets"][0]["owner_response_execution_authorized"] is False
    assert data["targets"][0]["owner_execution_authorized"] is True
    assert data["targets"][0]["controlled_execution_ready"] is True
    assert (
        data["targets"][0]["safe_credential_evidence_submission_status"]
        == "owner_execution_authorized_post_apply_readback_pending"
    )
    assert data["targets"][0]["safe_credential_raw_payload_storage_allowed"] is False
    assert (
        data["targets"][0]["safe_credential_private_clone_url_collection_allowed"]
        is False
    )
    controlled_preflight = data["controlled_execution_preflight"]
    assert controlled_preflight["authorization_ready"] is True
    assert controlled_preflight["preflight_ready"] is False
    assert controlled_preflight["github_write_channel_ready"] is False
    assert controlled_preflight["operator_unblock_required"] is True
    assert (
        controlled_preflight["operator_unblock_status"]
        == "github_account_suspended_external_action_required"
    )
    assert (
        "complete_github_account_suspension_appeal_or_provide_authorized_writable_namespace"
        in controlled_preflight["operator_unblock"]["required_actions"]
    )
    assert (
        "git push --dry-run origin HEAD:refs/heads/codex-github-write-channel-readonly-check"
        in controlled_preflight["operator_unblock"]["recheck_commands"]
    )
    assert controlled_preflight["blocked_preflight_target_count"] == 5
    governance_writeback = controlled_preflight["internal_governance_writeback"]
    assert governance_writeback["ready"] is True
    assert governance_writeback["mcp_evidence_packet_count"] == 1
    assert governance_writeback["rag_evidence_ref_count"] == 5
    assert governance_writeback["km_writeback_ready_count"] == 1
    assert governance_writeback["playbook_writeback_ready_count"] == 1
    assert governance_writeback["github_write_performed"] is False
    assert governance_writeback["operation_boundaries"]["github_api_allowed"] is False
    assert governance_writeback["operation_boundaries"]["gh_cli_allowed"] is False
    assert "192.168.0." not in response.text


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

    response = client.get("/api/v1/agents/github-target-controlled-execution-preflight")

    assert response.status_code == 200
    data = response.json()
    assert data["schema_version"] == "github_target_controlled_execution_preflight_v1"
    assert (
        data["status"] == "blocked_github_account_suspended_and_write_channel_required"
    )
    assert data["authorization_ready"] is True
    assert data["preflight_ready"] is False
    assert data["github_write_channel_ready"] is False
    assert data["github_account_status"] == "suspended"
    assert data["github_account_suspended"] is True
    assert data["github_api_forbidden_count"] == 6
    assert data["operator_unblock_required"] is True
    assert data["operator_unblock_status"] == (
        "github_account_suspended_external_action_required"
    )
    assert data["operator_unblock"]["github_account_suspended"] is True
    assert (
        "do_not_paste_pat_token_private_key_cookie_session_or_redacted_authorization_header"
        in data["operator_unblock"]["still_forbidden"]
    )
    assert data["github_create_repo_channel_ready"] is False
    assert data["github_refs_sync_channel_ready"] is False
    assert data["source_preflight_ready_count"] == 5
    assert data["controlled_apply_ready_count"] == 0
    assert data["blocked_preflight_target_count"] == 5
    assert data["github_connector_missing_target_404_count"] == 0
    assert data["operation_boundaries"]["controlled_apply_allowed"] is False
    assert data["operation_boundaries"]["secret_value_collection_allowed"] is False
    assert data["tool_channel_readback"]["gh_cli_write_ready"] is False
    assert data["internal_governance_writeback"]["ready"] is True
    assert data["internal_governance_writeback"]["km_writeback_ready_count"] == 1
    assert (
        data["internal_governance_writeback"]["playbook_writeback_ready_count"] == 1
    )
    assert data["internal_governance_writeback"]["github_api_called"] is False
    assert data["internal_governance_writeback"]["gh_cli_called"] is False
    assert (
        data["internal_governance_writeback"]["operation_boundaries"][
            "github_refs_sync_allowed"
        ]
        is False
    )
    assert data["targets"][0]["controlled_apply_ready"] is False
    assert "github_account_suspended_403" in data["targets"][0]["blockers"]
    assert "192.168.0." not in response.text


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

    response = client.post(
        "/api/v1/agents/github-target-owner-response-intake-preflight",
        json={
            "submission_mode": "read_only_markdown_response",
            "responses": [
                {
                    "template_id": "target-awoooi-refs-blocked",
                    "github_repo": "owenhytsai/awoooi",
                    "owner_role_or_team": "platform-owner",
                    "decision": "hold_pending_refs_truth",
                    "decision_reason": "Need refs truth review before sync.",
                    "affected_scope": "awoooi github backup target",
                    "redacted_evidence_refs": [
                        "docs/security/GITEA-GITHUB-MIGRATION-SNAPSHOT.md"
                    ],
                    "evidence_refs": [
                        "docs/security/source-control-ref-detail-diff.snapshot.json"
                    ],
                    "followup_owner": "platform-owner",
                    "rollback_owner": "platform-owner",
                    "maintenance_window": "not_authorized",
                    "validation_plan": "read-only refs truth review only",
                    "canonical_source": "gitea_main",
                    "github_target_disposition": "existing_private_candidate",
                    "visibility_review_owner": "platform-owner",
                    "refs_truth_review_owner": "platform-owner",
                    "private_clone_url_credential": (
                        "https://owner:ghp_1234567890abcdefghijklmnopqrstu@github.com/owenhytsai/awoooi.git"
                    ),
                }
            ],
        },
    )

    assert response.status_code == 200
    data = response.json()
    assert data["schema_version"] == "github_target_owner_response_intake_preflight_v1"
    assert data["status"] == "blocked_owner_response_intake_preflight"
    assert data["summary"]["preflight_passed_response_item_count"] == 0
    assert data["summary"]["preflight_blocked_response_item_count"] == 1
    assert data["summary"]["owner_response_received_count"] == 0
    assert data["summary"]["owner_response_accepted_count"] == 0
    assert data["summary"]["safe_credential_accepted_evidence_count"] == 0
    assert data["operation_boundaries"]["persist_submission_allowed"] is False
    assert data["operation_boundaries"]["github_api_write_allowed"] is False
    assert data["operation_boundaries"]["private_clone_url_collection_allowed"] is False
    assert data["authorization_flags"]["owner_response_execution_authorized"] is False
    assert data["responses"][0]["accepted_for_read_only_intake"] is False
    assert "forbidden_payload_detected" in data["responses"][0]["blockers"]
    assert "192.168.0." not in response.text


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

    response = client.post(
        "/api/v1/agents/github-target-safe-credential-evidence-reviewer-validation/validate-redacted-refs",
        json={
            "submission_mode": "redacted_metadata_pointer",
            "evidence_ref_submissions": [
                {
                    "template_id": "target-awoooi-refs-blocked",
                    "github_repo": "owenhytsai/awoooi",
                    "reviewer_role_or_team": "platform-owner",
                    "decision": "accept_redacted_evidence_refs_for_reviewer_validation",
                    "decision_reason": "Refs are redacted metadata pointers only.",
                    "evidence_ref_type": "redacted_metadata_pointer",
                    "redacted_evidence_refs": [
                        "docs/security/GITEA-GITHUB-MIGRATION-SNAPSHOT.md",
                        "owner-metadata:github-target-awoooi-redacted-ref",
                    ],
                    "affected_scope": "awoooi github private backup target",
                    "followup_owner": "platform-owner",
                    "validation_plan": "review redacted refs only; no GitHub write",
                }
            ],
        },
    )

    assert response.status_code == 200
    result = response.json()
    assert (
        result["status"] == "accepted_for_readonly_safe_credential_evidence_review_only"
    )
    assert result["summary"]["reviewer_validation_passed_count"] == 1
    assert result["summary"]["safe_credential_accepted_evidence_count"] == 0
    assert result["boundaries"]["payload_persisted"] is False
    assert result["boundaries"]["github_api_write_allowed"] is False
    assert result["boundaries"]["private_clone_url_collection_allowed"] is False

    readback = client.get(
        "/api/v1/agents/github-target-private-backup-evidence-gate"
    ).json()
    assert readback["summary"]["safe_credential_accepted_evidence_count"] == 0
    assert readback["summary"]["safe_credential_reviewer_validation_passed_count"] == 0
    assert (
        readback["summary"]["github_missing_target_create_private_repo_ready_count"]
        == 0
    )
    assert readback["summary"]["github_missing_target_refs_sync_ready_count"] == 0
    assert readback["summary"]["execution_ready_count"] == 9
    assert "192.168.0." not in response.text
