"""Phase 9: Ownership & Revalidation Queue

Revision ID: b035ownerq
Revises: b034dlm
Create Date: 2026-05-19

Uses raw SQL for all DDL to avoid SQLAlchemy before_create hook issues
with existing enum types.
"""

from typing import Union
from alembic import op
import sqlalchemy as sa

revision: str = "b035ownerq"
down_revision: Union[str, None] = "b034dlm"
branch_labels = None
depends_on = None


def upgrade() -> None:
    conn = op.get_bind()

    # ── Enums (idempotent) ────────────────────────────────────────────────────
    conn.execute(sa.text("""
        DO $$ BEGIN
            CREATE TYPE queue_priority AS ENUM ('critical', 'high', 'medium', 'low');
        EXCEPTION WHEN duplicate_object THEN NULL;
        END $$
    """))
    conn.execute(sa.text("""
        DO $$ BEGIN
            CREATE TYPE queue_status AS ENUM ('pending', 'in_progress', 'completed', 'dismissed');
        EXCEPTION WHEN duplicate_object THEN NULL;
        END $$
    """))
    conn.execute(sa.text("""
        DO $$ BEGIN
            CREATE TYPE queue_reason AS ENUM (
                'validation_expired', 'infra_change', 'osint_alert',
                'mitre_update', 'rule_modified', 'low_confidence', 'manual');
        EXCEPTION WHEN duplicate_object THEN NULL;
        END $$
    """))

    # ── technique_ownerships ──────────────────────────────────────────────────
    conn.execute(sa.text("""
        CREATE TABLE IF NOT EXISTS technique_ownerships (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            technique_id UUID NOT NULL UNIQUE
                REFERENCES techniques(id) ON DELETE CASCADE,
            owner_id UUID
                REFERENCES users(id) ON DELETE SET NULL,
            backup_owner_id UUID
                REFERENCES users(id) ON DELETE SET NULL,
            team VARCHAR(200),
            notes TEXT,
            assigned_at TIMESTAMP,
            assigned_by UUID
                REFERENCES users(id) ON DELETE SET NULL,
            created_at TIMESTAMP DEFAULT now(),
            updated_at TIMESTAMP DEFAULT now()
        )
    """))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_techown_owner_id ON technique_ownerships (owner_id)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_techown_technique_id ON technique_ownerships (technique_id)"
    ))

    # ── revalidation_queue_items ──────────────────────────────────────────────
    conn.execute(sa.text("""
        CREATE TABLE IF NOT EXISTS revalidation_queue_items (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            technique_id UUID
                REFERENCES techniques(id) ON DELETE CASCADE,
            detection_asset_id UUID
                REFERENCES detection_assets(id) ON DELETE CASCADE,
            priority queue_priority NOT NULL DEFAULT 'medium',
            reason queue_reason NOT NULL,
            reason_detail TEXT,
            status queue_status NOT NULL DEFAULT 'pending',
            assigned_to UUID
                REFERENCES users(id) ON DELETE SET NULL,
            due_date TIMESTAMP,
            created_at TIMESTAMP DEFAULT now(),
            completed_at TIMESTAMP,
            dismissed_at TIMESTAMP,
            completed_by UUID
                REFERENCES users(id) ON DELETE SET NULL,
            extra JSONB
        )
    """))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_rqueue_status ON revalidation_queue_items (status)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_rqueue_priority ON revalidation_queue_items (priority)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_rqueue_assigned_to ON revalidation_queue_items (assigned_to)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_rqueue_technique_id ON revalidation_queue_items (technique_id)"
    ))
    conn.execute(sa.text(
        "CREATE INDEX IF NOT EXISTS ix_rqueue_asset_id ON revalidation_queue_items (detection_asset_id)"
    ))


def downgrade() -> None:
    conn = op.get_bind()
    conn.execute(sa.text("DROP TABLE IF EXISTS revalidation_queue_items"))
    conn.execute(sa.text("DROP TABLE IF EXISTS technique_ownerships"))
    conn.execute(sa.text("DROP TYPE IF EXISTS queue_reason"))
    conn.execute(sa.text("DROP TYPE IF EXISTS queue_status"))
    conn.execute(sa.text("DROP TYPE IF EXISTS queue_priority"))
