"""Add account-scoped device_types table with platform seed data.

Revision ID: 073
Revises: b3c7e9f2a1d8
Create Date: 2026-04-12
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import UUID
import uuid


revision = "073"
down_revision = "b3c7e9f2a1d8"
branch_labels = None
depends_on = None

_PLATFORM_UUID = "00000000-0000-0000-0000-000000000001"
_CURRENT_ACCOUNT = (
    "COALESCE("
    "NULLIF(current_setting('app.current_account_id', TRUE), ''), "
    "'00000000-0000-0000-0000-000000000000'"
    ")::uuid"
)

SYSTEM_DEVICE_TYPES = [
    ("router", "Router", "network", 0),
    ("switch", "Switch", "network", 1),
    ("firewall", "Firewall", "network", 2),
    ("access-point", "Access Point", "network", 3),
    ("load-balancer", "Load Balancer", "network", 4),
    ("server", "Server", "compute", 0),
    ("workstation", "Workstation", "compute", 1),
    ("vm", "Virtual Machine", "compute", 2),
    ("container", "Container", "compute", 3),
    ("nas", "NAS", "storage", 0),
    ("san", "SAN", "storage", 1),
    ("cloud-storage", "Cloud Storage", "storage", 2),
    ("cloud", "Cloud", "cloud", 0),
    ("aws", "AWS", "cloud", 1),
    ("azure", "Azure", "cloud", 2),
    ("gcp", "Google Cloud", "cloud", 3),
    ("printer", "Printer", "endpoint", 0),
    ("phone", "Phone", "endpoint", 1),
    ("iot", "IoT Device", "endpoint", 2),
    ("camera", "Camera", "endpoint", 3),
    ("tablet", "Tablet", "endpoint", 4),
    ("laptop", "Laptop", "endpoint", 5),
    ("ups", "UPS", "infrastructure", 0),
    ("pdu", "PDU", "infrastructure", 1),
    ("rack", "Rack", "infrastructure", 2),
    ("patch-panel", "Patch Panel", "infrastructure", 3),
    ("nvr", "NVR", "security", 0),
    ("badge-reader", "Badge Reader", "security", 1),
]


def upgrade() -> None:
    op.create_table(
        "device_types",
        sa.Column("id", UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
        sa.Column("slug", sa.String(50), nullable=False),
        sa.Column("label", sa.String(100), nullable=False),
        sa.Column("category", sa.String(50), nullable=False),
        sa.Column("is_system", sa.Boolean(), nullable=False, server_default=sa.text("false")),
        sa.Column("account_id", UUID(as_uuid=True), sa.ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False),
        sa.Column("sort_order", sa.Integer(), nullable=False, server_default=sa.text("0")),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()")),
    )

    op.create_unique_constraint("uq_device_types_slug_account", "device_types", ["slug", "account_id"])
    op.create_index("ix_device_types_account_id", "device_types", ["account_id"])

    device_types_table = sa.table(
        "device_types",
        sa.column("id", UUID(as_uuid=True)),
        sa.column("slug", sa.String),
        sa.column("label", sa.String),
        sa.column("category", sa.String),
        sa.column("is_system", sa.Boolean),
        sa.column("account_id", UUID(as_uuid=True)),
        sa.column("sort_order", sa.Integer),
    )

    op.bulk_insert(device_types_table, [
        {
            "id": uuid.uuid4(),
            "slug": slug,
            "label": label,
            "category": category,
            "is_system": True,
            "account_id": uuid.UUID(_PLATFORM_UUID),
            "sort_order": sort_order,
        }
        for slug, label, category, sort_order in SYSTEM_DEVICE_TYPES
    ])

    op.execute("ALTER TABLE device_types ENABLE ROW LEVEL SECURITY")
    op.execute("ALTER TABLE device_types FORCE ROW LEVEL SECURITY")
    op.execute(f"""
        CREATE POLICY device_types_select ON device_types
        FOR SELECT
        USING (
            account_id = {_CURRENT_ACCOUNT}
            OR account_id = '{_PLATFORM_UUID}'::uuid
        )
    """)
    op.execute(f"""
        CREATE POLICY device_types_insert ON device_types
        FOR INSERT
        WITH CHECK (account_id = {_CURRENT_ACCOUNT})
    """)
    op.execute(f"""
        CREATE POLICY device_types_update ON device_types
        FOR UPDATE
        USING (account_id = {_CURRENT_ACCOUNT})
        WITH CHECK (account_id = {_CURRENT_ACCOUNT})
    """)
    op.execute(f"""
        CREATE POLICY device_types_delete ON device_types
        FOR DELETE
        USING (account_id = {_CURRENT_ACCOUNT})
    """)


def downgrade() -> None:
    op.execute("DROP POLICY IF EXISTS device_types_delete ON device_types")
    op.execute("DROP POLICY IF EXISTS device_types_update ON device_types")
    op.execute("DROP POLICY IF EXISTS device_types_insert ON device_types")
    op.execute("DROP POLICY IF EXISTS device_types_select ON device_types")
    op.execute("ALTER TABLE device_types DISABLE ROW LEVEL SECURITY")
    op.drop_table("device_types")
