"""Add models for OAuth and tweak AuditLog

Revision ID: 8d7729f5ed1f
Revises: 2b8bf1c3378e
Create Date: 2022-09-07 17:14:35.990594

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

import fief

# revision identifiers, used by Alembic.
revision = "8d7729f5ed1f"
down_revision = "2b8bf1c3378e"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "fief_oauth_providers",
        sa.Column("id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "created_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column("provider", sa.String(length=255), nullable=False),
        sa.Column("client_id", sa.Text(), nullable=False),
        sa.Column("client_secret", sa.Text(), nullable=False),
        sa.Column("scopes", sa.JSON(), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=True),
        sa.Column("openid_configuration_endpoint", sa.Text(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_fief_oauth_providers_created_at"),
        "fief_oauth_providers",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_oauth_providers_updated_at"),
        "fief_oauth_providers",
        ["updated_at"],
        unique=False,
    )
    op.create_table(
        "fief_oauth_accounts",
        sa.Column("id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "created_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column("access_token", sa.Text(), nullable=False),
        sa.Column(
            "expires_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            nullable=True,
        ),
        sa.Column("refresh_token", sa.Text(), nullable=True),
        sa.Column("account_id", sa.String(length=512), nullable=False),
        sa.Column("account_email", sa.String(length=512), nullable=True),
        sa.Column("oauth_provider_id", fief.models.generics.GUID(), nullable=False),
        sa.Column("user_id", fief.models.generics.GUID(), nullable=True),
        sa.Column("tenant_id", fief.models.generics.GUID(), nullable=False),
        sa.ForeignKeyConstraint(
            ["oauth_provider_id"], ["fief_oauth_providers.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(["tenant_id"], ["fief_tenants.id"], ondelete="CASCADE"),
        sa.ForeignKeyConstraint(["user_id"], ["fief_users.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("oauth_provider_id", "user_id"),
    )
    op.create_index(
        op.f("ix_fief_oauth_accounts_account_id"),
        "fief_oauth_accounts",
        ["account_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_oauth_accounts_created_at"),
        "fief_oauth_accounts",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_oauth_accounts_updated_at"),
        "fief_oauth_accounts",
        ["updated_at"],
        unique=False,
    )
    op.create_table(
        "fief_oauth_sessions",
        sa.Column("id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "created_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column("token", sa.String(length=255), nullable=False),
        sa.Column("redirect_uri", sa.Text(), nullable=False),
        sa.Column("oauth_provider_id", fief.models.generics.GUID(), nullable=False),
        sa.Column("login_session_id", fief.models.generics.GUID(), nullable=False),
        sa.Column("oauth_account_id", fief.models.generics.GUID(), nullable=True),
        sa.Column("tenant_id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "expires_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            nullable=False,
        ),
        sa.ForeignKeyConstraint(
            ["login_session_id"], ["fief_login_sessions.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(
            ["oauth_account_id"], ["fief_oauth_accounts.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(
            ["oauth_provider_id"], ["fief_oauth_providers.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(["tenant_id"], ["fief_tenants.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_fief_oauth_sessions_created_at"),
        "fief_oauth_sessions",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_oauth_sessions_expires_at"),
        "fief_oauth_sessions",
        ["expires_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_oauth_sessions_token"),
        "fief_oauth_sessions",
        ["token"],
        unique=True,
    )
    op.create_index(
        op.f("ix_fief_oauth_sessions_updated_at"),
        "fief_oauth_sessions",
        ["updated_at"],
        unique=False,
    )
    op.create_table(
        "fief_registration_sessions",
        sa.Column("id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "created_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column(
            "updated_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            server_default=sa.func.now(),
            nullable=False,
        ),
        sa.Column("token", sa.String(length=255), nullable=False),
        sa.Column("flow", sa.String(length=255), nullable=False),
        sa.Column("email", sa.String(length=320), nullable=True),
        sa.Column("oauth_account_id", fief.models.generics.GUID(), nullable=True),
        sa.Column("tenant_id", fief.models.generics.GUID(), nullable=False),
        sa.Column(
            "expires_at",
            fief.models.generics.TIMESTAMPAware(timezone=True),
            nullable=False,
        ),
        sa.ForeignKeyConstraint(
            ["oauth_account_id"], ["fief_oauth_accounts.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(["tenant_id"], ["fief_tenants.id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_fief_registration_sessions_created_at"),
        "fief_registration_sessions",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_registration_sessions_expires_at"),
        "fief_registration_sessions",
        ["expires_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_registration_sessions_token"),
        "fief_registration_sessions",
        ["token"],
        unique=True,
    )
    op.create_index(
        op.f("ix_fief_registration_sessions_updated_at"),
        "fief_registration_sessions",
        ["updated_at"],
        unique=False,
    )
    op.add_column(
        "fief_audit_logs",
        sa.Column("object_id", fief.models.generics.GUID(), nullable=True),
    )
    op.add_column(
        "fief_audit_logs",
        sa.Column("object_class", sa.String(length=255), nullable=True),
    )
    op.add_column(
        "fief_audit_logs",
        sa.Column("admin_user_id", fief.models.generics.GUID(), nullable=True),
    )
    op.add_column(
        "fief_audit_logs",
        sa.Column("admin_api_key_id", fief.models.generics.GUID(), nullable=True),
    )
    op.create_index(
        op.f("ix_fief_audit_logs_admin_api_key_id"),
        "fief_audit_logs",
        ["admin_api_key_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_audit_logs_admin_user_id"),
        "fief_audit_logs",
        ["admin_user_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_audit_logs_object_class"),
        "fief_audit_logs",
        ["object_class"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_audit_logs_object_id"),
        "fief_audit_logs",
        ["object_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_fief_audit_logs_subject_user_id"),
        "fief_audit_logs",
        ["subject_user_id"],
        unique=False,
    )

    connection = op.get_bind()
    if connection.dialect.name == "postgresql":
        op.drop_constraint(
            "fief_audit_logs_subject_user_id_fkey",
            "fief_audit_logs",
            type_="foreignkey",
        )
        op.drop_constraint(
            "fief_audit_logs_author_user_id_fkey", "fief_audit_logs", type_="foreignkey"
        )
        op.drop_column("fief_audit_logs", "author_user_id")
    elif connection.dialect.name == "mysql":
        op.drop_constraint(
            "fief_audit_logs_ibfk_1", "fief_audit_logs", type_="foreignkey"
        )
        op.drop_constraint(
            "fief_audit_logs_ibfk_2", "fief_audit_logs", type_="foreignkey"
        )
        op.drop_column("fief_audit_logs", "author_user_id")
    elif connection.dialect.name == "sqlite":
        with op.batch_alter_table("fief_audit_logs") as batch_op:
            batch_op.drop_column("author_user_id")
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "fief_audit_logs",
        sa.Column(
            "author_user_id", postgresql.UUID(), autoincrement=False, nullable=True
        ),
    )
    op.create_foreign_key(
        "fief_audit_logs_subject_user_id_fkey",
        "fief_audit_logs",
        "fief_users",
        ["subject_user_id"],
        ["id"],
        ondelete="SET NULL",
    )
    op.create_foreign_key(
        "fief_audit_logs_author_user_id_fkey",
        "fief_audit_logs",
        "fief_users",
        ["author_user_id"],
        ["id"],
        ondelete="SET NULL",
    )
    op.drop_index(
        op.f("ix_fief_audit_logs_subject_user_id"), table_name="fief_audit_logs"
    )
    op.drop_index(op.f("ix_fief_audit_logs_object_id"), table_name="fief_audit_logs")
    op.drop_index(op.f("ix_fief_audit_logs_object_class"), table_name="fief_audit_logs")
    op.drop_index(
        op.f("ix_fief_audit_logs_admin_user_id"), table_name="fief_audit_logs"
    )
    op.drop_index(
        op.f("ix_fief_audit_logs_admin_api_key_id"), table_name="fief_audit_logs"
    )
    op.drop_column("fief_audit_logs", "admin_api_key_id")
    op.drop_column("fief_audit_logs", "admin_user_id")
    op.drop_column("fief_audit_logs", "object_class")
    op.drop_column("fief_audit_logs", "object_id")
    op.drop_index(
        op.f("ix_fief_registration_sessions_updated_at"),
        table_name="fief_registration_sessions",
    )
    op.drop_index(
        op.f("ix_fief_registration_sessions_token"),
        table_name="fief_registration_sessions",
    )
    op.drop_index(
        op.f("ix_fief_registration_sessions_expires_at"),
        table_name="fief_registration_sessions",
    )
    op.drop_index(
        op.f("ix_fief_registration_sessions_created_at"),
        table_name="fief_registration_sessions",
    )
    op.drop_table("fief_registration_sessions")
    op.drop_index(
        op.f("ix_fief_oauth_sessions_updated_at"), table_name="fief_oauth_sessions"
    )
    op.drop_index(
        op.f("ix_fief_oauth_sessions_token"), table_name="fief_oauth_sessions"
    )
    op.drop_index(
        op.f("ix_fief_oauth_sessions_expires_at"), table_name="fief_oauth_sessions"
    )
    op.drop_index(
        op.f("ix_fief_oauth_sessions_created_at"), table_name="fief_oauth_sessions"
    )
    op.drop_table("fief_oauth_sessions")
    op.drop_index(
        op.f("ix_fief_oauth_accounts_updated_at"), table_name="fief_oauth_accounts"
    )
    op.drop_index(
        op.f("ix_fief_oauth_accounts_created_at"), table_name="fief_oauth_accounts"
    )
    op.drop_index(
        op.f("ix_fief_oauth_accounts_account_id"), table_name="fief_oauth_accounts"
    )
    op.drop_table("fief_oauth_accounts")
    op.drop_index(
        op.f("ix_fief_oauth_providers_updated_at"), table_name="fief_oauth_providers"
    )
    op.drop_index(
        op.f("ix_fief_oauth_providers_created_at"), table_name="fief_oauth_providers"
    )
    op.drop_table("fief_oauth_providers")
    # ### end Alembic commands ###
