"""Add revision status

Revision ID: deb7c1bae659
Revises: 056d1b302e38
Create Date: 2022-07-22 17:26:41.648281

"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base

# Define separate models to freeze the current setup at the time we wrote this
# migration.
Base = declarative_base()


class Page(Base):
    __tablename__ = "proof_pages"
    id = sa.Column(sa.Integer, primary_key=True)
    status_id = sa.Column(
        sa.Integer,
        sa.ForeignKey("proof_page_statuses.id"),
        index=True,
    )
    status = orm.relationship("PageStatus")
    revisions = orm.relationship("Revision")


class PageStatus(Base):
    __tablename__ = "proof_page_statuses"
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String)


class Revision(Base):
    __tablename__ = "proof_revisions"
    id = sa.Column(sa.Integer, primary_key=True)
    page_id = sa.Column(sa.Integer, sa.ForeignKey("proof_pages.id"), index=True)
    status_id = sa.Column(
        sa.Integer,
        sa.ForeignKey("proof_page_statuses.id"),
        index=True,
    )
    status = orm.relationship("PageStatus")


# revision identifiers, used by Alembic.
revision = "deb7c1bae659"
down_revision = "056d1b302e38"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.add_column(
        "proof_revisions", sa.Column("status_id", sa.Integer(), nullable=True)
    )
    op.create_index(
        op.f("ix_proof_revisions_status_id"),
        "proof_revisions",
        ["status_id"],
        unique=False,
    )
    with op.batch_alter_table("proof_revisions") as batch_op:
        batch_op.create_foreign_key(
            "proof_revisions", "proof_page_statuses", ["status_id"], ["id"]
        )

    # No revision has page status data. As a fallback, just copy the current
    # page status from the parent page to all revisions.
    bind = op.get_bind()
    session = orm.Session(bind=bind)
    for page in session.query(Page).all():
        for r in page.revisions:
            r.status = page.status
    session.commit()


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table("proof_revisions") as batch_op:
        batch_op.drop_constraint("proof_revisions", type_="foreignkey")
    op.drop_index(op.f("ix_proof_revisions_status_id"), table_name="proof_revisions")
    op.drop_column("proof_revisions", "status_id")
    # ### end Alembic commands ###
