"""OpenBao envelope encryption columns and key_access_log extensions.

Revision ID: 017
Revises: 016
Create Date: 2026-03-03

Adds Transit ciphertext columns (TEXT) alongside existing BYTEA columns
for dual-write migration strategy. Extends key_access_log with device_id,
justification, and correlation_id for Phase 29 audit trail.
"""

revision = "017"
down_revision = "016"
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import UUID


def upgrade() -> None:
    # --- Transit ciphertext columns (TEXT, alongside existing BYTEA) ---

    # devices: store OpenBao Transit ciphertext for credentials
    op.add_column(
        "devices",
        sa.Column("encrypted_credentials_transit", sa.Text(), nullable=True),
    )

    # certificate_authorities: Transit-encrypted CA private keys
    op.add_column(
        "certificate_authorities",
        sa.Column("encrypted_private_key_transit", sa.Text(), nullable=True),
    )

    # device_certificates: Transit-encrypted device cert private keys
    op.add_column(
        "device_certificates",
        sa.Column("encrypted_private_key_transit", sa.Text(), nullable=True),
    )

    # notification_channels: Transit-encrypted SMTP password
    op.add_column(
        "notification_channels",
        sa.Column("smtp_password_transit", sa.Text(), nullable=True),
    )

    # --- Tenant OpenBao key tracking ---
    op.add_column(
        "tenants",
        sa.Column("openbao_key_name", sa.Text(), nullable=True),
    )

    # --- Extend key_access_log for Phase 29 ---
    op.add_column(
        "key_access_log",
        sa.Column("device_id", UUID(as_uuid=True), nullable=True),
    )
    op.add_column(
        "key_access_log",
        sa.Column("justification", sa.Text(), nullable=True),
    )
    op.add_column(
        "key_access_log",
        sa.Column("correlation_id", sa.Text(), nullable=True),
    )

    # Add FK constraint for device_id -> devices(id) (nullable, so no cascade needed)
    op.create_foreign_key(
        "fk_key_access_log_device_id",
        "key_access_log",
        "devices",
        ["device_id"],
        ["id"],
    )


def downgrade() -> None:
    op.drop_constraint("fk_key_access_log_device_id", "key_access_log", type_="foreignkey")
    op.drop_column("key_access_log", "correlation_id")
    op.drop_column("key_access_log", "justification")
    op.drop_column("key_access_log", "device_id")
    op.drop_column("tenants", "openbao_key_name")
    op.drop_column("notification_channels", "smtp_password_transit")
    op.drop_column("device_certificates", "encrypted_private_key_transit")
    op.drop_column("certificate_authorities", "encrypted_private_key_transit")
    op.drop_column("devices", "encrypted_credentials_transit")
