"""stream_items

Revision: 0066
Revision ID: 16627338400e
Revises: 2daf3bc83d75
Create Date: 2016-07-19 12:15:23.760153

"""

# revision identifiers, used by Alembic.
revision = '16627338400e'
down_revision = '2daf3bc83d75'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

cards = sa.Table(
    'cards',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('parent_id', sa.Integer),
    sa.Column('parents_ids', postgresql.ARRAY(sa.Integer))
)

card_groups = sa.Table(
    'card_groups',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('parent_id', sa.Integer),
    sa.Column('auto_assign_user', sa.String)
)

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

    q = sa.select([card_groups.c.id, card_groups.c.auto_assign_user, card_groups.c.parent_id])\
            .where(card_groups.c.auto_assign_user!=None)

    card_q = sa.select([cards.c.id, cards.c.parent_id, cards.c.parents_ids])\
            .where(cards.c.id==sa.bindparam('cid'))

    attr_q = sa.text("""select a.title from attributes a
                    join attribute_groups ag on ag.id = a.group_id
                    join card_models cm on cm.attribute_group_id = ag.id
                    join card_enabled_models cem on cem.model_id = cm.id
                    join cards p on p.id = cem.card_id
                    join cards c on c.parents_ids[1] = p.id
                    where c.id = :cid and a.name = :name limit 1""")

    attr_top_q = sa.text("""select a.title from attributes a
                    join attribute_groups ag on ag.id = a.group_id
                    join card_models cm on cm.attribute_group_id = ag.id
                    join card_enabled_models cem on cem.model_id = cm.id
                    join cards p on p.id = cem.card_id
                    where p.id = :cid and a.name = :name limit 1""")

    updates = []
    for group in conn.execute(q):
        card = conn.execute(card_q, cid=group.parent_id).first()
        if not card:
            continue
        attr_title = conn.execute(attr_q if card.parent_id else attr_top_q,
            cid=card.id, name=group.auto_assign_user).scalar()
        updates.append({'gid': group.id, 'auto_assign_user': attr_title})

    if updates:
        conn.execute(card_groups.update().where(card_groups.c.id==sa.bindparam('gid')).values(
            auto_assign_user=sa.bindparam('auto_assign_user')), updates)

    op.execute("UPDATE card_attributes SET name = NULL WHERE attribute_id IS NOT NULL")
    op.execute("UPDATE attributes SET name = title")
    op.drop_column('attributes', 'title')
    op.create_index(op.f('ix_attributes_name'), 'attributes', ['name'], unique=False)

    op.add_column('views', sa.Column('name', sa.String(), nullable=True))
    op.execute("UPDATE views SET name = title")
    op.drop_column('views', 'title')

    op.create_table('card_log_types',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('card_id', sa.Integer(), nullable=False),
        sa.Column('created_by_id', sa.Integer(), nullable=True),
        sa.Column('created_at', sa.DateTime(), nullable=True),
        sa.Column('updated_at', sa.DateTime(), nullable=True),
        sa.Column('attribute_group_id', sa.Integer(), nullable=True),
        sa.Column('name', sa.String(), nullable=True),
        sa.ForeignKeyConstraint(['card_id'], ['cards.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['attribute_group_id'], ['attribute_groups.id'], ondelete='SET NULL'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_card_log_types_card_id'), 'card_log_types', ['card_id'], unique=False)
    op.create_index(op.f('ix_card_log_types_name'), 'card_log_types', ['name'], unique=False)

    op.create_table('card_logs',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('card_id', sa.Integer(), nullable=False),
        sa.Column('log_type_id', sa.Integer(), nullable=False),
        sa.Column('created_by_id', sa.Integer(), nullable=True),
        sa.Column('created_at', sa.DateTime(), nullable=True),
        sa.Column('updated_at', sa.DateTime(), nullable=True),
        sa.ForeignKeyConstraint(['card_id'], ['cards.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['log_type_id'], ['card_log_types.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['created_by_id'], ['users.id'], ondelete='SET NULL'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_card_logs_card_id'), 'card_logs', ['card_id'], unique=False)
    op.create_index(op.f('ix_card_logs_log_type_id'), 'card_logs', ['log_type_id'], unique=False)

    op.create_table('card_log_values',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('log_id', sa.Integer(), nullable=False),
        sa.Column('type_name', sa.String(), nullable=True),
        sa.Column('attribute_id', sa.Integer(), nullable=True),
        sa.Column('value', postgresql.JSONB(), nullable=True),
        sa.Column('unindexed_value', sa.Text(), nullable=True),
        sa.ForeignKeyConstraint(['log_id'], ['card_logs.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['attribute_id'], ['attributes.id'], ondelete='CASCADE'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_card_log_values_log_id'), 'card_log_values', ['log_id'], unique=False)
    op.create_index(op.f('ix_card_log_values_attribute_id'), 'card_log_values', ['attribute_id'], unique=False)
    op.create_index(op.f('ix_card_log_values_value'), 'card_log_values', ['value'], unique=False)


def downgrade():
    pass
