"""LDAP integration: ldap_configs table + user auth_provider/ldap_dn columns

Revision ID: 0004_ldap
Revises: 0003_absences
Create Date: 2026-03-27
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "0004_ldap"
down_revision = "0003_absences"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # Add auth_provider enum
    authprovider = postgresql.ENUM("local", "ldap", name="authprovider", create_type=False)
    authprovider.create(op.get_bind(), checkfirst=True)

    # Alter users table
    op.add_column("users", sa.Column(
        "auth_provider",
        sa.Enum("local", "ldap", name="authprovider"),
        nullable=False,
        server_default="local",
    ))
    op.add_column("users", sa.Column("ldap_dn", sa.Text(), nullable=True))
    op.alter_column("users", "password_hash", nullable=True)

    # Create ldap_configs table
    op.create_table(
        "ldap_configs",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column("company_id", postgresql.UUID(as_uuid=True),
                  sa.ForeignKey("companies.id", ondelete="CASCADE"),
                  nullable=False, unique=True),
        sa.Column("enabled", sa.Boolean(), nullable=False, server_default="false"),
        sa.Column("host", sa.String(255), nullable=False),
        sa.Column("port", sa.Integer(), nullable=False, server_default="389"),
        sa.Column("use_ssl", sa.Boolean(), nullable=False, server_default="false"),
        sa.Column("use_tls", sa.Boolean(), nullable=False, server_default="false"),
        sa.Column("bind_dn", sa.Text(), nullable=False),
        sa.Column("bind_password_encrypted", sa.Text(), nullable=False),
        sa.Column("base_dn", sa.Text(), nullable=False),
        sa.Column("user_search_filter", sa.String(512), nullable=False,
                  server_default="(objectClass=person)"),
        sa.Column("attr_email", sa.String(100), nullable=False, server_default="mail"),
        sa.Column("attr_firstname", sa.String(100), nullable=False, server_default="givenName"),
        sa.Column("attr_lastname", sa.String(100), nullable=False, server_default="sn"),
        sa.Column("attr_username", sa.String(100), nullable=False, server_default="sAMAccountName"),
        sa.Column("attr_department", sa.String(100), nullable=True),
        sa.Column("last_sync_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
    )
    op.create_index("ix_ldap_configs_company_id", "ldap_configs", ["company_id"])


def downgrade() -> None:
    op.drop_table("ldap_configs")
    op.drop_column("users", "ldap_dn")
    op.drop_column("users", "auth_provider")
    # LDAP users have no password_hash — set placeholder before restoring NOT NULL
    op.execute("UPDATE users SET password_hash = 'LDAP_USER_NO_PASSWORD' WHERE password_hash IS NULL")
    op.alter_column("users", "password_hash", nullable=False)
    op.execute("DROP TYPE IF EXISTS authprovider")
