"""Create linker table workflow_apscheduler.

Revision ID: 961eddbd4c13
Revises: 850dccac3b02
Create Date: 2025-11-18 10:38:57.211087

"""

from uuid import uuid4

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "961eddbd4c13"
down_revision = "850dccac3b02"
branch_labels = None
depends_on = None

# NOTE: this migration forgot to insert these workflows with is_task=true. Make sure to correct that if you copy this.
workflows = [
    {
        "name": "task_validate_subscriptions",
        "description": "Validate subscriptions",
        "workflow_id": uuid4(),
        "target": "SYSTEM",
    },
]


def _create_workflows() -> None:
    conn = op.get_bind()
    for workflow in workflows:
        conn.execute(
            sa.text(
                "INSERT INTO workflows VALUES (:workflow_id, :name, :target, :description, now()) ON CONFLICT DO NOTHING"
            ),
            workflow,
        )


def _downgrade_create_workflows() -> None:
    conn = op.get_bind()
    for workflow in workflows:
        conn.execute(sa.text("DELETE FROM workflows WHERE name = :name"), {"name": workflow["name"]})


def _create_apscheduler_jobs_table_if_not_exists() -> None:
    # Check if the apscheduler_jobs table exists and create it if it does not exist.
    conn = op.get_bind()
    inspector = sa.inspect(conn)
    if "apscheduler_jobs" not in inspector.get_table_names():
        op.execute(
            sa.text(
                """
                CREATE TABLE apscheduler_jobs
                (
                    id            VARCHAR(191) NOT NULL PRIMARY KEY,
                    next_run_time DOUBLE PRECISION,
                    job_state     bytea NOT NULL
                );
                """
            )
        )


def _create_workflows_table_if_not_exists() -> None:
    # Notice the VARCHAR(512) for schedule_id to accommodate longer IDs
    # This so that if APScheduler changes its ID format in the future, we are covered.
    op.execute(
        sa.text(
            """
                CREATE TABLE workflows_apscheduler_jobs (
                    workflow_id UUID NOT NULL,
                    schedule_id VARCHAR(512) NOT NULL,
                    PRIMARY KEY (workflow_id, schedule_id),
                    CONSTRAINT fk_workflow
                        FOREIGN KEY (workflow_id) REFERENCES public.workflows (workflow_id)
                            ON DELETE CASCADE,
                    CONSTRAINT fk_schedule
                        FOREIGN KEY (schedule_id) REFERENCES public.apscheduler_jobs (id)
                            ON DELETE CASCADE,
                    CONSTRAINT uq_workflow_schedule UNIQUE (workflow_id, schedule_id)
                );
            """
        )
    )

    op.create_index("ix_workflows_apscheduler_jobs_schedule_id", "workflows_apscheduler_jobs", ["schedule_id"])


def upgrade() -> None:
    _create_apscheduler_jobs_table_if_not_exists()
    _create_workflows_table_if_not_exists()
    _create_workflows()


def downgrade() -> None:
    op.execute(
        sa.text(
            """
            DROP TABLE IF EXISTS workflows_apscheduler_jobs;
            """
        )
    )
    _downgrade_create_workflows()
