"""update fauc

Revision ID: 89f407c298c8
Revises: Add hoc creation to recover databases before alembic migrations
Create Date: 2025-01-18 10:58:45.626725

"""

from typing import Sequence, Union
import warnings

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "89f407c298c8"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "aregisters",
        sa.Column("id", sa.String(), nullable=False),
        sa.Column(
            "the_type",
            sa.String(length=32),
            nullable=True,
            comment="type of the register (identifcation, user-comments, vocabulary, etc.)",
        ),
        sa.Column("the_date", sa.String(), nullable=True),
        sa.Column(
            "dbase",
            sa.String(),
            nullable=True,
            comment="name of the exporting database",
        ),
        sa.Column(
            "replace_mode",
            sa.String(),
            nullable=True,
            comment="backup mode means the file is ignored by default on import",
        ),
        sa.Column(
            "kleiofile", sa.String(), nullable=True, comment="path of the kleio file"
        ),
        sa.Column("obs", sa.String(), nullable=True, comment="observations"),
        sa.ForeignKeyConstraint(
            ["id"],
            ["entities.id"],
            name=op.f("fk_aregisters_id_entities"),
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_aregisters")),
        if_not_exists=True,
    )
    op.create_index(
        op.f("ix_aregisters_kleiofile"), "aregisters", ["kleiofile"], unique=False,
        if_not_exists=True
    )
    op.create_index(
        op.f("ix_aregisters_the_date"), "aregisters", ["the_date"], unique=False,
        if_not_exists=True
    )

    # links
    op.drop_table("links", if_exists=True)
    op.create_table(
        "links",
        sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
        sa.Column("rid", sa.String(length=64), nullable=False),
        sa.Column("entity", sa.String(length=64), nullable=True),
        sa.Column("user", sa.String(length=64), nullable=False),
        sa.Column("rule", sa.String(length=4096), nullable=False),
        sa.Column(
            "status",
            sa.Enum(
                "UNLINKED",
                "AUTOMATIC",
                "SOURCE",
                "MANUAL",
                "MHK",
                "N",
                "INVALID",
                name="linkstatus",
            ),
            nullable=False,
        ),
        sa.Column("source", sa.String(length=64), nullable=True),
        sa.Column("aregister", sa.String(length=64), nullable=True),
        sa.ForeignKeyConstraint(
            ["aregister"],
            ["aregisters.id"],
            name=op.f("fk_links_aregister_aregisters"),
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["entity"], ["entities.id"], name=op.f("fk_links_entity_entities"),

        ),
        sa.ForeignKeyConstraint(
            ["rid"],
            ["rentities.id"],
            name=op.f("fk_links_rid_rentities"),
            ondelete="CASCADE",
        ),
        sa.ForeignKeyConstraint(
            ["source"],
            ["sources.id"],
            name=op.f("fk_links_source_sources"),
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_links")),
        sa.UniqueConstraint("rid", "entity", "user", name="unique_link")
    )
    op.create_index(
        op.f("ix_links_entity"), "links", ["entity"], unique=False, if_not_exists=True
    )
    op.create_index(
        op.f("ix_links_rid"), "links", ["rid"], unique=False, if_not_exists=True
    )
    op.create_index(
        op.f("ix_links_source"), "links", ["source"], unique=False, if_not_exists=True
    )

    op.drop_table("robjects", if_exists=True)
    op.drop_table("goods", if_exists=True)
    op.drop_table("rpersons", if_exists=True)
    op.drop_table("rgeoentities", if_exists=True)

    # contraints
    try:
        op.drop_constraint(None, "acts", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("acts") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_acts_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    try:
        op.drop_constraint(None, "attributes", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("attributes") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_attributes_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )
    with op.batch_alter_table("class_attributes") as batch_op:
        batch_op.alter_column(
            "colname",
            existing_type=sa.VARCHAR(length=32),
            nullable=False,
        )
        batch_op.alter_column(
            "colclass",
            existing_type=sa.VARCHAR(length=32),
            nullable=False,
        )
        batch_op.alter_column("coltype", existing_type=sa.VARCHAR(), nullable=False)
        batch_op.alter_column("colsize", existing_type=sa.INTEGER(), nullable=False)
        batch_op.alter_column(
            "colprecision", existing_type=sa.INTEGER(), nullable=False
        )
        batch_op.alter_column("pkey", existing_type=sa.INTEGER(), nullable=False)

    with op.batch_alter_table("classes") as batch_op:
        batch_op.alter_column("table_name", existing_type=sa.VARCHAR(), nullable=False)

    try:
        op.drop_constraint(None, "classes", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("classes") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_classes_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    # Column changes entities

    op.add_column("entities", sa.Column("the_source", sa.String(), nullable=True))

    with op.batch_alter_table("entities") as batch_op:
        batch_op.alter_column("class", existing_type=sa.VARCHAR(), nullable=False)

    try:
        op.drop_constraint(None, "entities", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    # Geoentities
    op.create_index(op.f("ix_geoentities_name"), "geoentities", ["name"], unique=False,
                    if_not_exists=True)

    try:
        op.drop_constraint(None, "geoentities", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("geoentities") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_geoentities_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    # Kleiofiles
    with op.batch_alter_table("kleiofiles") as batch_op:
        batch_op.alter_column("imported", existing_type=sa.DATETIME(), nullable=True)
        batch_op.alter_column(
            "imported_string",
            existing_type=sa.VARCHAR(length=255),
            nullable=True,
        )

    # objects
    try:
        op.drop_constraint(None, "objects", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("objects") as batch_op:
        batch_op.alter_column(
            "the_type", existing_type=sa.VARCHAR(length=32), nullable=False
        )
        batch_op.create_foreign_key(
            op.f("fk_objects_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    # persons
    op.create_index(
        op.f("ix_persons_name"), "persons", ["name"], unique=False, if_not_exists=True
    )
    try:
        op.drop_constraint(None, "persons", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("persons") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_persons_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    # relations
    try:
        op.drop_constraint(None, "relations", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("relations") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_relations_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    # Rentities
    try:
        op.drop_constraint(None, "rentities", type_="foreignkey")
    except Exception as e:
        print(f"Warning: updating constraints (normal in old databases): {e}")

    with op.batch_alter_table("rentities") as batch_op:
        batch_op.alter_column(
            "user", existing_type=sa.VARCHAR(length=64), nullable=False
        )
        batch_op.alter_column(
            "description",
            existing_type=sa.VARCHAR(length=128),
            type_=sa.String(length=4096),
            nullable=False,
        )
        batch_op.alter_column(
            "status",
            existing_type=sa.VARCHAR(length=64),
            type_=sa.Enum(
                "UNLINKED",
                "AUTOMATIC",
                "SOURCE",
                "MANUAL",
                "MHK",
                "N",
                "INVALID",
                name="linkstatus",
            ),
            nullable=False,
        )
        batch_op.create_foreign_key(
            op.f("fk_rentities_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )

    try:
        op.drop_column("rentities", "the_class")
    except Exception as e:
        warnings.warn(f"Error dropping column 'the_class' from 'rentities': {e}", stacklevel=2)

    # sources
    try:
        op.drop_constraint(None, "sources", type_="foreignkey")
    except Exception as e:
        warnings.warn(f"Warning: updating constraints (normal in old databases): {e}", stacklevel=2)

    with op.batch_alter_table("sources") as batch_op:
        batch_op.create_foreign_key(
            op.f("fk_sources_id_entities"),
            "entities",
            ["id"],
            ["id"],
            ondelete="CASCADE",
        )
    # ### end Alembic commands ###


def downgrade() -> None:
    pass
    # ### end Alembic commands ###
