"""convert_choice_attr_to_groups

Revision: 0133
Revision ID: 4cee323fc652
Revises: 4c4163218424
Create Date: 2018-04-17 12:11:17.101847

"""

# revision identifiers, used by Alembic.
revision = '4cee323fc652'
down_revision = '4c4163218424'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql import select
from sqlalchemy.dialects import postgresql
import datetime


attributes = sa.Table(
    'attributes',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('group_id', sa.Integer),
    sa.Column('type_name', sa.String),
    sa.Column('name', sa.String),
    sa.Column('is_from_integration', sa.String),
    sa.Column('options', sa.PickleType)
)

attribute_groups = sa.Table(
    'attribute_groups',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('owner_id', sa.Integer)
)

cards = sa.Table(
    'cards',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('cache_id', sa.String)
)

card_attributes = sa.Table(
    'card_attributes',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('attribute_id', sa.Integer),
    sa.Column('card_id', sa.Integer),
    sa.Column('value', postgresql.JSONB)
)

card_group_types = sa.Table(
    'card_group_types',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('created_at', sa.DateTime),
    sa.Column('owner_id', sa.Integer),
    sa.Column('attribute_id', sa.Integer),
    sa.Column('scope', sa.String),
    sa.Column('one_group_per_card', sa.Boolean),
    sa.Column('auto_random_color', sa.Boolean),
    sa.Column('display_on_card', sa.String),
    sa.Column('is_project_specific', sa.Boolean),
    sa.Column('cache_id', sa.String)
)

card_groups = sa.Table(
    'card_groups',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('created_at', sa.DateTime),
    sa.Column('group_type_id', sa.Integer),
    sa.Column('parent_id', sa.Integer),
    sa.Column('title', sa.String),
    sa.Column('position', sa.Integer),
    sa.Column('is_archived', sa.Boolean),
    sa.Column('show_flow_indicator', sa.Boolean),
    sa.Column('always_show_description', sa.Boolean),
    sa.Column('disallow_direct_card_creation', sa.Boolean),
    sa.Column('cache_id', sa.String)
)

card_groups_cards = sa.Table(
    'card_groups_cards',
    sa.MetaData(),
    sa.Column('card_id', sa.Integer),
    sa.Column('group_id', sa.Integer),
    sa.Column('position', sa.Integer)
)

card_models = sa.Table(
    'card_models',
    sa.MetaData(),
    sa.Column('attribute_group_id', sa.Integer),
    sa.Column('cache_id', sa.String)
)


def upgrade():
    conn = op.get_bind()

    for attr in conn.execute(attributes.select().where(sa.and_(attributes.c.type_name == 'choice', attributes.c.is_from_integration == None))):
        owner_id = conn.execute(select([attribute_groups.c.owner_id]).where(attribute_groups.c.id==attr.group_id)).scalar()
        multi = attr.options and attr.options.get('multi')
        r = conn.execute(card_group_types.insert().values(
            created_at=datetime.datetime.utcnow(),
            owner_id=owner_id,
            attribute_id=attr.id,
            scope='org',
            one_group_per_card=not multi,
            auto_random_color=False,
            display_on_card='label',
            is_project_specific=False,
            cache_id=sa.func.uuid_generate_v4()
        ))
        gt_id = r.inserted_primary_key[0]

        conn.execute(attributes.update().where(attributes.c.id==attr.id).values(
            type_name='group_type', options={'one_group_per_card': not multi, 'auto_random_color': False}))

        if attr.options and attr.options.get('items'):
            for i, title in enumerate(attr.options['items']):
                r = conn.execute(card_groups.insert().values(
                    created_at=datetime.datetime.utcnow(),
                    group_type_id=gt_id,
                    parent_id=None,
                    title=title,
                    position=i,
                    is_archived=False,
                    show_flow_indicator=False,
                    always_show_description=False,
                    disallow_direct_card_creation=False,
                    cache_id=sa.func.uuid_generate_v4()
                ))
                gid = r.inserted_primary_key[0]
                q = select([card_attributes.c.card_id], distinct=True).where(
                        sa.and_(card_attributes.c.attribute_id==attr.id, card_attributes.c.value.op('?')(title)))
                for j, r in enumerate(conn.execute(q)):
                    conn.execute(card_groups_cards.insert().values(group_id=gid, card_id=r[0], position=j))

        conn.execute(cards.update().where(sa.and_(card_attributes.c.card_id == cards.c.id, card_attributes.c.attribute_id==attr.id))\
            .values(cache_id=sa.func.uuid_generate_v4()))
        conn.execute(card_attributes.delete().where(card_attributes.c.attribute_id==attr.id))

    conn.execute(card_models.update().where(sa.and_(attributes.c.group_id == card_models.c.attribute_group_id, attributes.c.type_name == 'group_type'))\
        .values(cache_id=sa.func.uuid_generate_v4()))


def downgrade():
    pass
