"""add test_platforms table

Revision ID: a7dff4777ffb
Revises: 8a9b7c6d5e4f
Create Date: 2025-12-01 12:50:37.268889

"""

from collections.abc import Sequence

import sqlalchemy as sa
import sqlmodel.sql.sqltypes

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "a7dff4777ffb"  # pragma: allowlist secret
down_revision: str | Sequence[str] | None = "8a9b7c6d5e4f"  # pragma: allowlist secret
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "test_platforms",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("test_id", sa.Integer(), nullable=False),
        sa.Column("operating_system_id", sa.Integer(), nullable=True),
        sa.Column("operating_system_name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
        sa.Column("category", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
        sa.ForeignKeyConstraint(
            ["test_id"],
            ["tests.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    with op.batch_alter_table("test_platforms", schema=None) as batch_op:
        batch_op.create_index(batch_op.f("ix_test_platforms_category"), ["category"], unique=False)
        batch_op.create_index(
            batch_op.f("ix_test_platforms_operating_system_name"),
            ["operating_system_name"],
            unique=False,
        )
        batch_op.create_index(batch_op.f("ix_test_platforms_test_id"), ["test_id"], unique=False)

    # Backfill from existing Test.data.requirements JSON
    # Uses SQLite json_each() to extract platform requirements
    op.execute("""
        INSERT INTO test_platforms (
            test_id, operating_system_id, operating_system_name, category
        )
        SELECT DISTINCT
            t.id as test_id,
            CAST(
                json_extract(req.value, '$.operating_system.id') AS INTEGER
            ) as operating_system_id,
            json_extract(req.value, '$.operating_system.name')
                as operating_system_name,
            json_extract(req.value, '$.category.key') as category
        FROM tests t, json_each(json_extract(t.data, '$.requirements')) as req
        WHERE json_extract(t.data, '$.requirements') IS NOT NULL
          AND json_extract(req.value, '$.operating_system.name') IS NOT NULL
    """)

    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table("test_platforms", schema=None) as batch_op:
        batch_op.drop_index(batch_op.f("ix_test_platforms_test_id"))
        batch_op.drop_index(batch_op.f("ix_test_platforms_operating_system_name"))
        batch_op.drop_index(batch_op.f("ix_test_platforms_category"))

    op.drop_table("test_platforms")
    # ### end Alembic commands ###
