"""Phase 13: Executive Dashboard — posture_snapshots table.

Revision ID: b039exec
Revises:     b038risk
Create Date: 2026-05-20
"""

from alembic import op
import sqlalchemy as sa

revision       = "b039exec"
down_revision  = "b038risk"
branch_labels  = None
depends_on     = None


def upgrade() -> None:
    conn = op.get_bind()
    conn.execute(sa.text("""
        CREATE TABLE IF NOT EXISTS posture_snapshots (
            id              UUID         PRIMARY KEY DEFAULT gen_random_uuid(),
            snapshot_date   DATE         NOT NULL,

            -- Coverage
            total_techniques   INTEGER NOT NULL DEFAULT 0,
            validated_count    INTEGER NOT NULL DEFAULT 0,
            partial_count      INTEGER NOT NULL DEFAULT 0,
            not_covered_count  INTEGER NOT NULL DEFAULT 0,
            coverage_pct       FLOAT   NOT NULL DEFAULT 0.0,

            -- Risk
            avg_risk_score     FLOAT   NOT NULL DEFAULT 0.0,
            critical_count     INTEGER NOT NULL DEFAULT 0,
            high_count         INTEGER NOT NULL DEFAULT 0,
            medium_count       INTEGER NOT NULL DEFAULT 0,
            low_count          INTEGER NOT NULL DEFAULT 0,

            -- Operations
            open_queue_items   INTEGER NOT NULL DEFAULT 0,
            orphan_techniques  INTEGER NOT NULL DEFAULT 0,

            -- Knowledge
            playbook_count     INTEGER NOT NULL DEFAULT 0,
            lesson_count       INTEGER NOT NULL DEFAULT 0,

            -- MTTD
            mttd_avg_seconds   FLOAT,
            executions_30d     INTEGER NOT NULL DEFAULT 0,
            detection_rate_30d FLOAT,

            -- Meta
            created_by  UUID REFERENCES users(id) ON DELETE SET NULL,
            created_at  TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
            extra       JSONB
        )
    """))

    # Unique constraint: one snapshot per calendar day
    conn.execute(sa.text("""
        DO $$ BEGIN
            ALTER TABLE posture_snapshots
                ADD CONSTRAINT uq_posture_snapshot_date UNIQUE (snapshot_date);
        EXCEPTION WHEN duplicate_table THEN NULL;
                 WHEN duplicate_object THEN NULL;
        END $$
    """))

    # Index for date-range trend queries
    conn.execute(sa.text("""
        CREATE INDEX IF NOT EXISTS ix_posture_snapshots_date
            ON posture_snapshots (snapshot_date)
    """))


def downgrade() -> None:
    conn = op.get_bind()
    conn.execute(sa.text("DROP TABLE IF EXISTS posture_snapshots CASCADE"))
