"""候選審核 queue review_state writer operator run readiness preview。

本模組只檢查正式 CLI 更新 review_state 前的操作員證據是否齊備；
不讀 approval token、不執行 CLI、不開 DB connection、不更新 review_state、
不 commit、不掛 scheduler。
"""


FORBIDDEN_TOKEN_KEYWORDS = (
    "approval_token",
    "approval-token",
    "market_intel_queue_write_approval",
)


def _as_dict(value):
    return value if isinstance(value, dict) else {}


def _has_text(value):
    return bool(isinstance(value, str) and value.strip())


def _contains_forbidden_token_key(value):
    if isinstance(value, dict):
        for key, nested in value.items():
            normalized_key = str(key).lower()
            if any(token_key in normalized_key for token_key in FORBIDDEN_TOKEN_KEYWORDS):
                return True
            if _contains_forbidden_token_key(nested):
                return True
    elif isinstance(value, list):
        return any(_contains_forbidden_token_key(item) for item in value)
    return False


def _payload_manifest(run_package):
    return _as_dict(_as_dict(run_package).get("payload_manifest"))


def _payload_count(run_package):
    return int(_payload_manifest(run_package).get("payload_count") or 0)


def _artifact_summary(operator_evidence):
    artifact_paths = {
        "review_state_transaction_json_path": operator_evidence.get(
            "review_state_transaction_json_path"
        ),
        "backup_artifact_path": operator_evidence.get("backup_artifact_path"),
        "preflight_artifact_path": operator_evidence.get("preflight_artifact_path"),
    }
    return {
        "provided_keys": sorted(operator_evidence.keys()),
        "artifact_path_count": sum(1 for value in artifact_paths.values() if _has_text(value)),
        "review_state_transaction_json_path_recorded": _has_text(
            artifact_paths["review_state_transaction_json_path"]
        ),
        "backup_artifact_path_recorded": _has_text(
            artifact_paths["backup_artifact_path"]
        ),
        "preflight_artifact_path_recorded": _has_text(
            artifact_paths["preflight_artifact_path"]
        ),
        "operator_acknowledged_shell_only_token": bool(
            operator_evidence.get("operator_acknowledged_shell_only_token")
        ),
        "operator_confirmed_review_state_preflight_only": bool(
            operator_evidence.get("operator_confirmed_review_state_preflight_only")
        ),
        "approval_token_submitted_to_api": _contains_forbidden_token_key(
            operator_evidence
        ),
    }


def _readiness_gates(
    *,
    run_package,
    operator_drill,
    postwrite_smoke,
    operator_evidence,
):
    artifact_summary = _artifact_summary(operator_evidence)
    payload_count = _payload_count(run_package)
    run_package = _as_dict(run_package)
    operator_drill = _as_dict(operator_drill)
    return [
        {
            "key": "run_package_preview_available",
            "label": "review_state run package preview 已產生",
            "passed": run_package.get("mode")
            == "candidate_queue_review_decision_writer_run_package_preview",
        },
        {
            "key": "payload_manifest_available",
            "label": "run package 已包含 review_state update payload manifest",
            "passed": bool(_payload_manifest(run_package).get("manifest_hash")),
        },
        {
            "key": "payload_count_within_small_batch_limit",
            "label": "首次 review_state operator run 必須是 1 到 5 筆小流量",
            "passed": 0 < payload_count <= 5,
        },
        {
            "key": "operator_drill_ready",
            "label": "operator drill 已提供 review_state CLI 操作順序",
            "passed": bool(operator_drill.get("operator_drill_ready")),
        },
        {
            "key": "review_state_transaction_json_path_recorded",
            "label": "操作員已記錄 review_state transaction JSON 檔案路徑",
            "passed": artifact_summary[
                "review_state_transaction_json_path_recorded"
            ],
        },
        {
            "key": "backup_artifact_path_recorded",
            "label": "操作員已記錄最新備份檔路徑",
            "passed": artifact_summary["backup_artifact_path_recorded"],
        },
        {
            "key": "preflight_artifact_path_recorded",
            "label": "操作員已記錄 CLI read-only preflight 輸出路徑",
            "passed": artifact_summary["preflight_artifact_path_recorded"],
        },
        {
            "key": "operator_confirmed_review_state_preflight_only",
            "label": "操作員確認 preflight 只讀且不更新 review_state",
            "passed": artifact_summary[
                "operator_confirmed_review_state_preflight_only"
            ],
        },
        {
            "key": "operator_acknowledged_shell_only_token",
            "label": "操作員確認一次性 token 只在 CLI shell 提供",
            "passed": artifact_summary["operator_acknowledged_shell_only_token"],
        },
        {
            "key": "approval_token_not_submitted_to_api",
            "label": "payload 不得包含 approval token 或 token key",
            "passed": not artifact_summary["approval_token_submitted_to_api"],
        },
        {
            "key": "postwrite_smoke_plan_available",
            "label": "post-write smoke 已可在更新後做只讀驗證",
            "passed": bool(postwrite_smoke),
        },
    ]


def build_candidate_queue_review_decision_writer_run_readiness(
    *,
    transaction_preview,
    writer_preflight,
    writer_status,
    postwrite_smoke,
    operator_drill,
    run_package,
    operator_evidence=None,
):
    """建立 review_state operator run readiness preview；不執行任何副作用。"""
    operator_evidence = _as_dict(operator_evidence)
    artifact_summary = _artifact_summary(operator_evidence)
    gates = _readiness_gates(
        run_package=run_package,
        operator_drill=operator_drill,
        postwrite_smoke=postwrite_smoke,
        operator_evidence=operator_evidence,
    )
    blocked_reasons = [gate["key"] for gate in gates if not gate["passed"]]
    ready_for_cli_operator_run = bool(not blocked_reasons)
    manifest = _payload_manifest(run_package)
    transaction_summary = _as_dict(transaction_preview.get("transaction_summary"))

    return {
        "mode": "candidate_queue_review_decision_writer_run_readiness_preview",
        "target_table": "market_alert_review_queue",
        "target_operation": "update_review_state",
        "ready_for_cli_operator_run": ready_for_cli_operator_run,
        "ready_for_api_review_state_update": False,
        "ready_for_api_database_write": False,
        "ready_for_scheduler_attach": False,
        "api_executes_cli": False,
        "api_reads_approval_token": False,
        "api_writes_file": False,
        "api_writes_database": False,
        "api_updates_review_state": False,
        "approval_record_written": False,
        "decision_record_written": False,
        "review_state_update_executed": False,
        "database_connection_opened": False,
        "database_session_created": False,
        "explicit_transaction_opened": False,
        "transaction_opened": False,
        "transaction_committed": False,
        "database_write_executed": False,
        "database_commit_executed": False,
        "database_rollback_executed": False,
        "external_network_executed": False,
        "scheduler_attached": False,
        "writes_executed": False,
        "would_write_database": False,
        "blocked_reasons": blocked_reasons,
        "gates": gates,
        "operator_evidence_summary": artifact_summary,
        "run_package_summary": {
            "mode": run_package.get("mode"),
            "package_ready": bool(run_package.get("package_ready")),
            "payload_count": int(manifest.get("payload_count") or 0),
            "manifest_hash": manifest.get("manifest_hash"),
            "required_artifact_count": len(run_package.get("required_artifacts") or []),
            "command_count": len(run_package.get("command_bundle") or []),
        },
        "writer_summary": {
            "writer_status_mode": writer_status.get("mode"),
            "writer_preflight_mode": writer_preflight.get("mode"),
            "postwrite_smoke_mode": postwrite_smoke.get("mode"),
            "transaction_statement_count": int(
                transaction_summary.get("statement_count") or 0
            ),
        },
        "cli_execution_boundary": {
            "api_may_execute_cli": False,
            "operator_shell_required": True,
            "one_time_token_shell_only": True,
            "requires_backup_verified": True,
            "requires_review_state_transaction_json": True,
            "requires_read_only_preflight": True,
            "requires_postwrite_smoke_after_cli": True,
        },
        "next_operator_steps": [
            "保存 review_state transaction JSON",
            "執行並記錄最新備份檔路徑",
            "執行 read-only preflight 並保存輸出",
            "確認一次性 approval token 只在 CLI shell 注入",
            "CLI 更新後立即保存 writer output 與 post-write smoke 結果",
        ],
        "safe_boundaries": [
            "do_not_execute_review_state_writer_from_run_readiness_api",
            "do_not_read_approval_token_from_run_readiness_api",
            "do_not_create_review_state_run_artifacts_from_api",
            "do_not_open_database_connection_from_review_state_run_readiness",
            "do_not_update_review_state_from_review_state_run_readiness",
            "do_not_attach_scheduler_from_review_state_run_readiness",
            "no_remove_orphans",
            "no_momo_db_lifecycle_change",
        ],
    }
