"""non-org grouptypes to projects

Revision: 0072
Revision ID: 44182012460b
Revises: 4ed4e16e500e
Create Date: 2016-09-07 15:00:09.809749

"""

# revision identifiers, used by Alembic.
revision = '44182012460b'
down_revision = '4ed4e16e500e'
branch_labels = None
depends_on = None

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

group_types = sa.Table(
    'card_group_types',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('owner_id', sa.Integer),
    sa.Column('name', sa.String),
    sa.Column('singular_name', sa.String),
    sa.Column('plural_name', sa.String),
    sa.Column('scope', sa.String),
    sa.Column('one_group_per_card', sa.Boolean),
    sa.Column('display_on_card', sa.String),
    sa.Column('auto_random_color', sa.Boolean),
    sa.Column('builtin', sa.String),
    sa.Column('auto_enabled_on_new_projects', sa.Boolean),
    sa.Column('is_project_specific', sa.Boolean),
    sa.Column('created_by_id', sa.Integer),
    sa.Column('created_at', sa.DateTime),
    sa.Column('updated_at', sa.DateTime),
    sa.Column('icon', sa.String),
    sa.Column('description', sa.Text),
    sa.Column('cache_id', sa.String),
    sa.Column('attribute_id', sa.Integer)
)

project_enabled_group_types = sa.Table(
    'project_enabled_group_types',
    sa.MetaData(),
    sa.Column('group_type_id', sa.Integer()),
    sa.Column('project_id', 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('group_type_id', sa.Integer),
    sa.Column('title', sa.String),
    sa.Column('color', sa.String),
    sa.Column('position', sa.Integer)
)

projects = sa.Table(
    'projects',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('owner_id', sa.Integer),
    sa.Column('top_level_card_id', sa.Integer),
    sa.Column('attribute_group_id', sa.Integer),
    sa.Column('use_org_attributes', sa.Boolean)
)

views = sa.Table(
    'views',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('project_id', sa.Integer),
    sa.Column('group_type_id', sa.Integer)
)

cards = sa.Table(
    'cards',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('project_id', sa.Integer),
    sa.Column('parent_id', sa.Integer),
    sa.Column('board_created', sa.Boolean)
)

def upgrade():
    done = {}
    conn = op.get_bind()

    def copy_gt(gt, project):
        r = conn.execute(group_types.insert().values(
            owner_id=gt.owner_id,
            name=gt.name,
            singular_name=gt.singular_name,
            plural_name=gt.plural_name,
            scope=gt.scope,
            one_group_per_card=gt.one_group_per_card,
            display_on_card=gt.display_on_card,
            auto_random_color=gt.auto_random_color,
            created_by_id=gt.created_by_id,
            created_at=gt.created_at,
            updated_at=gt.updated_at,
            icon=gt.icon,
            description=gt.description,
            builtin=gt.builtin,
            attribute_id=gt.attribute_id,
            cache_id=uuid.uuid4(),
            auto_enabled_on_new_projects=False,
            is_project_specific=True
        ))
        gt_id = r.inserted_primary_key[0]
        conn.execute(card_groups.update().where(sa.and_(card_groups.c.group_type_id == gt.id, card_groups.c.parent_id == project.top_level_card_id)).values(
            group_type_id = gt_id
        ))
        sub_stmt = sa.select([cards.c.id]).where(sa.and_(cards.c.project_id == project.id, cards.c.parent_id != None))
        conn.execute(card_groups.update().where(sa.and_(card_groups.c.group_type_id == gt.id, card_groups.c.parent_id.in_(sub_stmt))).values(
            group_type_id = gt_id
        ))
        return gt_id

    for gt in conn.execute(group_types.select().where(sa.and_(group_types.c.is_project_specific == False, group_types.c.scope != 'org'))):
        if gt.attribute_id is not None:
            continue
        for project_id in conn.execute(project_enabled_group_types.select().where(project_enabled_group_types.c.group_type_id == gt.id)):
            project = conn.execute(projects.select().where(projects.c.id == project_id[1])).first()
            done_id = "{0}-{1}".format(gt.id, project.id)
            if done_id in done:
                continue
            gt_id = copy_gt(gt, project)
            conn.execute(project_enabled_group_types.insert().values(
                group_type_id=gt_id,
                project_id=project.id
            ))
            conn.execute(views.update().where(sa.and_(views.c.group_type_id == gt.id, views.c.project_id == project.id)).values(
                group_type_id = gt_id
            ))
            done[done_id] = True
        op.execute("DELETE FROM card_group_types WHERE id = %s" % gt.id)


def downgrade():
    pass
