"""Card templates

Revision: 0027
Revision ID: 13c9e3e73486
Revises: 4c29125461b8
Create Date: 2015-09-21 16:53:32.123224

"""

# revision identifiers, used by Alembic.
revision = '13c9e3e73486'
down_revision = '4c29125461b8'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy import and_
from sqlalchemy.dialects import postgresql
from sqlalchemy.ext.mutable import MutableDict
from frasco.utils import slugify
import uuid

templateshelper = sa.Table(
    'board_templates',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('name', sa.String),
    sa.Column('created_at', sa.DateTime),
    sa.Column('owner_id', sa.Integer),
    sa.Column('created_by_id', sa.Integer),
    sa.Column('builtin', sa.Boolean),
)

templatelistshelper = sa.Table(
    'board_template_lists',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('board_template_id', sa.Integer),
    sa.Column('title', sa.String),
    sa.Column('bgcolor', sa.String),
    sa.Column('show_flow_indicator', sa.Boolean),
    sa.Column('card_state', sa.String),
    sa.Column('description', sa.Text),
    sa.Column('icon', sa.String),
)

cardsheleper = sa.Table(
    'cards',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('title', sa.String),
    sa.Column('created_at', sa.DateTime),
    sa.Column('owner_id', sa.Integer),
    sa.Column('created_by_id', sa.Integer),
    sa.Column('is_template', sa.Boolean),
    sa.Column('parents_ids', postgresql.ARRAY(sa.Integer)),
    sa.Column('ref', sa.Integer),
    sa.Column('ref_counter', sa.Integer),
    sa.Column('model_id', sa.Integer),
    sa.Column('board_created', sa.Boolean),
    sa.Column('state', sa.String),
    sa.Column('is_link', sa.Boolean),
    sa.Column('link_has_own_attributes', sa.Boolean),
    sa.Column('slug', sa.String),
    sa.Column('public_permission', sa.Integer),
    sa.Column('default_child_card_model_id', sa.Integer),
    sa.Column('list_position', sa.Integer),
    sa.Column('org_members_can_observe', sa.Integer),
    sa.Column('org_members_can_autojoin', sa.Integer),
    sa.Column('default_org_member_permission', sa.Integer),
    sa.Column('is_archived', sa.Boolean),
    sa.Column('is_list_archived', sa.Boolean),
    sa.Column('is_parent_archived', sa.Integer),
    sa.Column('meta', MutableDict.as_mutable(postgresql.JSONB)),
    sa.Column('push_id', sa.String),
)

cardlistshelper = sa.Table(
    'card_lists',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('parent_id', sa.Integer),
    sa.Column('title', sa.String),
    sa.Column('created_at', sa.DateTime),
    sa.Column('owner_id', sa.Integer),
    sa.Column('created_by_id', sa.Integer),
    sa.Column('parents_ids', postgresql.ARRAY(sa.Integer)),
    sa.Column('card_state', sa.String),
    sa.Column('position', sa.Integer),
    sa.Column('bgcolor', sa.String),
    sa.Column('show_flow_indicator', sa.Boolean),
    sa.Column('description', sa.Text),
    sa.Column('icon', sa.String),
    sa.Column('disallow_direct_card_creation', sa.Boolean),
    sa.Column('is_archived', sa.Boolean),
    sa.Column('is_parent_archived', sa.Integer),
    sa.Column('meta', MutableDict.as_mutable(sa.PickleType)),
)

orgshelper = sa.Table(
    'organizations',
    sa.MetaData(),
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('default_card_model_id', sa.Integer),
)


def create_slug(title):
    title_slug = slugify(title, max_length=40, word_boundary=True)
    slug = "%s-%s" % (str(uuid.uuid4())[:8], title_slug)
    return slug

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

    op.add_column('card_models', sa.Column('card_template_id', sa.Integer(), nullable=True))
    op.create_foreign_key('card_models_card_template_id_fkey', 'card_models', 'cards', ['card_template_id'], ['id'], ondelete='SET NULL')
    op.add_column('cards', sa.Column('is_template', sa.Boolean(), nullable=True))
    op.execute("UPDATE cards SET is_template = FALSE")

    for template in connection.execute(templateshelper.select().where(templateshelper.c.builtin == False)):
        res = connection.execute(
            orgshelper.select().where(and_(
                orgshelper.c.id == template.owner_id,
            ))).first()
        model_id = res[1]

        res = connection.execute(
            cardsheleper.insert().values(
                title=template.name,
                created_at=template.created_at,
                owner_id=template.owner_id,
                created_by_id=template.created_by_id,
                is_template=True,
                parents_ids=[],
                ref=0,
                ref_counter=0,
                model_id=model_id,
                board_created=True,
                state="undecided",
                is_link=False,
                link_has_own_attributes=False,
                slug=create_slug(template.name),
                public_permission=0,
                default_child_card_model_id=model_id,
                list_position=0,
                org_members_can_observe=True,
                org_members_can_autojoin=False,
                default_org_member_permission=4,
                is_archived=False,
                is_list_archived=False,
                is_parent_archived=0,
                meta={},
                push_id=uuid.uuid4(),
            )
        )
        card_id = res.inserted_primary_key[0]
        pos = 0
        for tpl_list in connection.execute(templatelistshelper.select().where(templatelistshelper.c.board_template_id == template.id)):
            res = connection.execute(
                cardlistshelper.insert().values(
                    parent_id=card_id,
                    title=tpl_list.title,
                    created_at=template.created_at,
                    created_by_id=template.created_by_id,
                    parents_ids=[card_id],
                    position=pos,
                    is_archived=False,
                    is_parent_archived=0,
                    meta={},
                    bgcolor=tpl_list.bgcolor,
                    show_flow_indicator=tpl_list.show_flow_indicator,
                    description=tpl_list.description,
                    icon=tpl_list.icon,
                    card_state=tpl_list.card_state,
                    disallow_direct_card_creation=False,
                )
            )
            pos = pos+1
    ### end Alembic commands ###


def downgrade():
    connection = op.get_bind()
    connection.execute(
        cardsheleper.delete().where(cardsheleper.c.is_template == True)
    )

    op.drop_column('cards', 'is_template')
    op.drop_constraint('card_models_card_template_id_fkey', 'card_models', type_='foreignkey')
    op.drop_column('card_models', 'card_template_id')


    ### end Alembic commands ###
