"""
Add Tag, TagKind and ManifestChild tables.

Revision ID: 10f45ee2310b
Revises: 13411de1c0ff
Create Date: 2018-10-29 15:22:53.552216
"""

# revision identifiers, used by Alembic.
revision = "10f45ee2310b"
down_revision = "13411de1c0ff"

import sqlalchemy as sa
from util.migrate import UTF8CharField


def upgrade(op, tables, tester):
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "tagkind",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=False),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_tagkind")),
    )
    op.create_index("tagkind_name", "tagkind", ["name"], unique=True)
    op.create_table(
        "manifestchild",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("repository_id", sa.Integer(), nullable=False),
        sa.Column("manifest_id", sa.Integer(), nullable=False),
        sa.Column("child_manifest_id", sa.Integer(), nullable=False),
        sa.ForeignKeyConstraint(
            ["child_manifest_id"],
            ["manifest.id"],
            name=op.f("fk_manifestchild_child_manifest_id_manifest"),
        ),
        sa.ForeignKeyConstraint(
            ["manifest_id"], ["manifest.id"], name=op.f("fk_manifestchild_manifest_id_manifest")
        ),
        sa.ForeignKeyConstraint(
            ["repository_id"],
            ["repository.id"],
            name=op.f("fk_manifestchild_repository_id_repository"),
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_manifestchild")),
    )
    op.create_index(
        "manifestchild_child_manifest_id", "manifestchild", ["child_manifest_id"], unique=False
    )
    op.create_index("manifestchild_manifest_id", "manifestchild", ["manifest_id"], unique=False)
    op.create_index(
        "manifestchild_manifest_id_child_manifest_id",
        "manifestchild",
        ["manifest_id", "child_manifest_id"],
        unique=True,
    )
    op.create_index("manifestchild_repository_id", "manifestchild", ["repository_id"], unique=False)
    op.create_index(
        "manifestchild_repository_id_child_manifest_id",
        "manifestchild",
        ["repository_id", "child_manifest_id"],
        unique=False,
    )
    op.create_index(
        "manifestchild_repository_id_manifest_id",
        "manifestchild",
        ["repository_id", "manifest_id"],
        unique=False,
    )
    op.create_index(
        "manifestchild_repository_id_manifest_id_child_manifest_id",
        "manifestchild",
        ["repository_id", "manifest_id", "child_manifest_id"],
        unique=False,
    )
    op.create_table(
        "tag",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=False),
        sa.Column("repository_id", sa.Integer(), nullable=False),
        sa.Column("manifest_id", sa.Integer(), nullable=True),
        sa.Column("lifetime_start_ms", sa.BigInteger(), nullable=False),
        sa.Column("lifetime_end_ms", sa.BigInteger(), nullable=True),
        sa.Column("hidden", sa.Boolean(), nullable=False, server_default=sa.sql.expression.false()),
        sa.Column(
            "reversion", sa.Boolean(), nullable=False, server_default=sa.sql.expression.false()
        ),
        sa.Column("tag_kind_id", sa.Integer(), nullable=False),
        sa.Column("linked_tag_id", sa.Integer(), nullable=True),
        sa.ForeignKeyConstraint(
            ["linked_tag_id"], ["tag.id"], name=op.f("fk_tag_linked_tag_id_tag")
        ),
        sa.ForeignKeyConstraint(
            ["manifest_id"], ["manifest.id"], name=op.f("fk_tag_manifest_id_manifest")
        ),
        sa.ForeignKeyConstraint(
            ["repository_id"], ["repository.id"], name=op.f("fk_tag_repository_id_repository")
        ),
        sa.ForeignKeyConstraint(
            ["tag_kind_id"], ["tagkind.id"], name=op.f("fk_tag_tag_kind_id_tagkind")
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_tag")),
    )
    op.create_index("tag_lifetime_end_ms", "tag", ["lifetime_end_ms"], unique=False)
    op.create_index("tag_linked_tag_id", "tag", ["linked_tag_id"], unique=False)
    op.create_index("tag_manifest_id", "tag", ["manifest_id"], unique=False)
    op.create_index("tag_repository_id", "tag", ["repository_id"], unique=False)
    op.create_index("tag_repository_id_name", "tag", ["repository_id", "name"], unique=False)
    op.create_index(
        "tag_repository_id_name_hidden", "tag", ["repository_id", "name", "hidden"], unique=False
    )
    op.create_index(
        "tag_repository_id_name_lifetime_end_ms",
        "tag",
        ["repository_id", "name", "lifetime_end_ms"],
        unique=True,
    )
    op.create_index(
        "tag_repository_id_name_tag_kind_id",
        "tag",
        ["repository_id", "name", "tag_kind_id"],
        unique=False,
    )
    op.create_index("tag_tag_kind_id", "tag", ["tag_kind_id"], unique=False)
    # ### end Alembic commands ###

    op.bulk_insert(
        tables.tagkind,
        [
            {"name": "tag"},
        ],
    )

    # ### population of test data ### #
    tester.populate_table(
        "tag",
        [
            ("repository_id", tester.TestDataType.Foreign("repository")),
            ("tag_kind_id", tester.TestDataType.Foreign("tagkind")),
            ("name", tester.TestDataType.String),
            ("manifest_id", tester.TestDataType.Foreign("manifest")),
            ("lifetime_start_ms", tester.TestDataType.BigInteger),
        ],
    )

    tester.populate_table(
        "manifestchild",
        [
            ("repository_id", tester.TestDataType.Foreign("repository")),
            ("manifest_id", tester.TestDataType.Foreign("manifest")),
            ("child_manifest_id", tester.TestDataType.Foreign("manifest")),
        ],
    )
    # ### end population of test data ### #


def downgrade(op, tables, tester):
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table("tag")
    op.drop_table("manifestchild")
    op.drop_table("tagkind")
    # ### end Alembic commands ###
