"""Add persistent MCP Gateway scope, canary evidence, and idempotency state."""

from alembic import op

revision = "20260719_80"
down_revision = "20260719_70"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.execute(
        """
        ALTER TABLE public.dataflow_workflow_versions
            ADD COLUMN business_domain VARCHAR(200) NOT NULL DEFAULT 'legacy',
            ADD COLUMN created_by_subject VARCHAR(200) NOT NULL DEFAULT 'legacy',
            ADD COLUMN write_authorized BOOLEAN NOT NULL DEFAULT FALSE;

        CREATE INDEX idx_workflow_versions_gateway_scope
            ON public.dataflow_workflow_versions(
                business_domain, environment, status, version_no DESC
            );

        ALTER TABLE public.workflow_plan_audits
            ADD COLUMN actor_subject VARCHAR(200) NOT NULL DEFAULT 'legacy';

        ALTER TABLE public.workflow_plan_audits
            DROP CONSTRAINT IF EXISTS workflow_plan_audits_decision_check;
        ALTER TABLE public.workflow_plan_audits
            DROP CONSTRAINT IF EXISTS ck_workflow_plan_audits_decision;
        ALTER TABLE public.workflow_plan_audits
            ADD CONSTRAINT ck_workflow_plan_audits_decision
                CHECK (decision IN (
                    'allowed', 'rejected', 'failed', 'recorded',
                    'idempotent_replay'
                ));

        CREATE TABLE public.workflow_canary_evidence (
            id UUID PRIMARY KEY,
            workflow_version_id UUID NOT NULL
                REFERENCES public.dataflow_workflow_versions(id)
                ON DELETE CASCADE,
            engine_execution_id VARCHAR(255) NOT NULL,
            baseline_execution_id VARCHAR(255),
            status VARCHAR(20) NOT NULL
                CHECK (status IN ('started', 'passed', 'failed')),
            sample_runs INTEGER NOT NULL DEFAULT 0 CHECK (sample_runs >= 0),
            verified_by VARCHAR(200),
            verification_summary JSONB NOT NULL DEFAULT '{}'::jsonb,
            created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
            verified_at TIMESTAMPTZ,
            UNIQUE (engine_execution_id)
        );
        CREATE INDEX idx_workflow_canary_version_created
            ON public.workflow_canary_evidence(
                workflow_version_id, created_at DESC
            );

        CREATE TABLE public.workflow_gateway_operations (
            id UUID PRIMARY KEY,
            workflow_version_id UUID
                REFERENCES public.dataflow_workflow_versions(id)
                ON DELETE SET NULL,
            action VARCHAR(80) NOT NULL,
            idempotency_key VARCHAR(500) NOT NULL,
            status VARCHAR(20) NOT NULL
                CHECK (status IN ('claimed', 'succeeded', 'failed')),
            result JSONB NOT NULL DEFAULT '{}'::jsonb,
            safe_error VARCHAR(1000),
            actor_subject VARCHAR(200) NOT NULL,
            correlation_id UUID NOT NULL,
            created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
            UNIQUE (action, idempotency_key)
        );
        CREATE INDEX idx_workflow_gateway_operations_version
            ON public.workflow_gateway_operations(
                workflow_version_id, action, created_at DESC
            );

        ALTER TABLE public.workflow_runs
            ADD COLUMN parent_run_id UUID
                REFERENCES public.workflow_runs(id) ON DELETE SET NULL,
            ADD COLUMN attempt INTEGER NOT NULL DEFAULT 1 CHECK (attempt > 0),
            ADD COLUMN run_metadata JSONB NOT NULL DEFAULT '{}'::jsonb;
        CREATE INDEX idx_workflow_runs_parent
            ON public.workflow_runs(parent_run_id, attempt);
        """
    )


def downgrade() -> None:
    op.execute(
        """
        DROP TABLE IF EXISTS public.workflow_gateway_operations;
        DROP TABLE IF EXISTS public.workflow_canary_evidence;

        DROP INDEX IF EXISTS public.idx_workflow_runs_parent;
        ALTER TABLE public.workflow_runs
            DROP COLUMN IF EXISTS run_metadata,
            DROP COLUMN IF EXISTS attempt,
            DROP COLUMN IF EXISTS parent_run_id;

        UPDATE public.workflow_plan_audits
        SET decision = 'recorded'
        WHERE decision = 'idempotent_replay';

        ALTER TABLE public.workflow_plan_audits
            DROP CONSTRAINT IF EXISTS ck_workflow_plan_audits_decision;
        ALTER TABLE public.workflow_plan_audits
            ADD CONSTRAINT workflow_plan_audits_decision_check
                CHECK (decision IN (
                    'allowed', 'rejected', 'failed', 'recorded'
                ));
        ALTER TABLE public.workflow_plan_audits
            DROP COLUMN IF EXISTS actor_subject;

        DROP INDEX IF EXISTS public.idx_workflow_versions_gateway_scope;
        ALTER TABLE public.dataflow_workflow_versions
            DROP COLUMN IF EXISTS write_authorized,
            DROP COLUMN IF EXISTS created_by_subject,
            DROP COLUMN IF EXISTS business_domain;
        """
    )
