import os

import pytest
from sqlalchemy import create_engine, text

from app.core.common.identifiers import new_governance_uid
from app.core.orchestration.migration.dual_run import DualRunMode
from app.core.orchestration.migration.repository import PostgresMigrationStore

pytestmark = pytest.mark.skipif(
    os.getenv("RUN_V55_PERSISTENCE_INTEGRATION") != "1",
    reason="set RUN_V55_PERSISTENCE_INTEGRATION=1",
)


def test_cutover_state_and_outbox_commit_atomically_and_idempotently():
    engine = create_engine(
        os.environ["DATAOPS_MCP_TEST_DATABASE_URL"], pool_pre_ping=True
    )
    store = PostgresMigrationStore(engine)
    dataflow_uid = new_governance_uid()
    correlation_id = new_governance_uid()
    idempotency_key = f"cutover:{dataflow_uid}:v55"
    state = None
    operation = None
    try:
        state = store.create_state(
            {
                "dataflow_uid": dataflow_uid,
                "environment": "test",
                "mode": DualRunMode.N8N_PRIMARY_KESTRA_SHADOW.value,
                "n8n_definition_id": f"n8n-{dataflow_uid}",
                "kestra_definition_id": f"kestra-{dataflow_uid}",
                "migration_batch": "low_risk",
            }
        )
        dual_run_id = store.record_dual_run(
            {
                "dataflow_uid": dataflow_uid,
                "environment": "test",
                "input_snapshot_hash": "a" * 64,
                "primary_execution_id": "n8n-v55-persistence",
                "shadow_execution_id": "kestra-v55-persistence",
                "primary_status": "success",
                "shadow_status": "success",
                "isolation": {"strategy": "read_only"},
                "formal_engine_changed": False,
                "correlation_id": correlation_id,
            }
        )
        report_id = store.record_reconciliation(
            {
                "state_id": state["state_id"],
                "dual_run_id": dual_run_id,
                "status": "passed",
                "policy": {},
                "safe_metrics": {"row_count_delta": 0},
                "differences": [],
                "correlation_id": correlation_id,
            }
        )
        assert dual_run_id
        assert report_id
        record = {
            "dataflow_uid": dataflow_uid,
            "environment": "test",
            "source_mode": DualRunMode.N8N_PRIMARY_KESTRA_SHADOW.value,
            "target_mode": DualRunMode.KESTRA_PRIMARY_N8N_STANDBY.value,
            "n8n_definition_id": state["n8n_definition_id"],
            "kestra_definition_id": state["kestra_definition_id"],
            "gates": {"reconciliation_passed": True},
            "idempotency_key": idempotency_key,
            "correlation_id": correlation_id,
        }

        claimed, operation = store.request_transition(record)
        replay_claimed, replay = store.request_transition(record)

        assert claimed is True
        assert replay_claimed is False
        assert replay["operation_id"] == operation["operation_id"]
        with engine.connect() as connection:
            event = connection.execute(
                text(
                    "SELECT event_type, payload "
                    "FROM public.outbox_events "
                    "WHERE aggregate_id = :operation_id"
                ),
                {"operation_id": operation["operation_id"]},
            ).one()
        assert event[0] == "workflow.engine.cutover.requested"
        assert event[1]["idempotency_key"] == idempotency_key
        assert "password" not in repr(event[1]).lower()

        store.complete_transition(
            operation["operation_id"],
            DualRunMode.KESTRA_PRIMARY_N8N_STANDBY.value,
            {"status": "succeeded"},
        )
        current = store.get_state(dataflow_uid, "test")
        assert current["mode"] == "kestra_primary_n8n_standby"
        assert current["status"] == "stable"
    finally:
        if state:
            store.delete_test_state(state["state_id"])
        engine.dispose()
