"""Link a network device to a catalog model.

Machines, PCs and printers all carry modelnumberid, which is what lets an asset
detail page show the photo uploaded against its vendor model. Network devices
carried only vendorid, so NetworkDeviceDetail.vue rendered a hero image bound to
`networkdevice.imageurl` that nothing could ever populate - a feature that
looked present and could not work.

Nullable, with no backfill: a device whose model is not recorded is normal, and
guessing one from the vendor would put wrong photos on real hardware.
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'network0002model'
down_revision = 'network0001anchor'
branch_labels = None
depends_on = None


def upgrade():
    # Guarded exactly like employees0002photo. On a FRESH database the tables
    # are built from the SQLAlchemy models, which already declare this column,
    # so an unconditional add fails with "duplicate column name". On an existing
    # server the column really is missing and gets added.
    bind = op.get_bind()
    insp = sa.inspect(bind)
    if 'networkdevices' not in insp.get_table_names():
        return
    cols = {c['name'] for c in insp.get_columns('networkdevices')}
    if 'modelnumberid' not in cols:
        op.add_column('networkdevices', sa.Column('modelnumberid', sa.Integer(), nullable=True))
        # Only where it is possible. SQLite has no ALTER TABLE ADD CONSTRAINT,
        # and routing this through batch_alter_table - which rebuilds the table -
        # made Alembic's column sort raise "Circular dependency detected". The
        # column is what the relationship needs; the constraint is integrity on
        # the real database.
        if bind.dialect.name != 'sqlite':
            op.create_foreign_key(
                'fk_networkdevices_modelnumberid',
                'networkdevices', 'models',
                ['modelnumberid'], ['modelnumberid'],
            )


def downgrade():
    bind = op.get_bind()
    insp = sa.inspect(bind)
    if 'networkdevices' not in insp.get_table_names():
        return
    cols = {c['name'] for c in insp.get_columns('networkdevices')}
    if 'modelnumberid' in cols:
        if bind.dialect.name != 'sqlite':
            op.drop_constraint('fk_networkdevices_modelnumberid', 'networkdevices',
                               type_='foreignkey')
        op.drop_column('networkdevices', 'modelnumberid')
