"""
Copy iplistrecord and iplistpurpose tables to a separate database (imunify360-ipsetlists.db),
it should be attached while running im360 migrations.
"""

from peewee import (
    CharField,
    CompositeKey,
    IntegerField,
    Model,
)

# Define the tables to move
TABLES_TO_COPY = (
    "iplistrecord",
    "iplistpurpose",
)


class IPListRecord(Model):
    network_address = IntegerField(null=False)
    netmask = IntegerField(null=False)
    version = IntegerField(null=False)
    iplist_id = IntegerField(null=False)

    class Meta:
        db_table = "iplistrecord"
        primary_key = CompositeKey(
            "network_address", "netmask", "version", "iplist_id"
        )
        schema = "ipsetlists"


class IPListPurpose(Model):
    purpose = CharField(null=False)
    iplist_id = IntegerField(null=False)

    class Meta:
        db_table = "iplistpurpose"
        primary_key = CompositeKey("purpose", "iplist_id")
        schema = "ipsetlists"


def migrate(migrator, database, fake=False, **kwargs):
    # Create new tables in the new database
    migrator.create_model(IPListRecord)
    migrator.create_model(IPListPurpose)

    for table in TABLES_TO_COPY:
        columns = ",".join(
            f.column_name for f in migrator.orm[table]._meta.sorted_fields
        )

        # Remove all data from new database/table to avoid conflicts.
        # Ideally, the table should already be empty, but sometimes it's not.
        migrator.sql(f"DELETE FROM ipsetlists.{table}")

        # Copy data to the new database
        migrator.sql(
            f"INSERT INTO ipsetlists.{table} ({columns}) "
            f"SELECT {columns} FROM resident.{table}"
        )

    # Re-create indexes
    for table, field in [
        ("iplistrecord", "network_address"),
        ("iplistrecord", "netmask"),
        ("iplistpurpose", "purpose"),
    ]:
        migrator.sql(
            f'CREATE INDEX IF NOT EXISTS ipsetlists."{table}_{field}" ON'
            f" {table} ({field})"
        )


def rollback(migrator, database, fake=False, **kwargs):
    pass
