"""project_auto_actions

Revision: 0175
Revision ID: 4d90b902c3e0
Revises: ace95229377
Create Date: 2019-10-02 22:15:22.803369

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


# revision identifiers, used by Alembic.
revision = '4d90b902c3e0'
down_revision = 'ace95229377'
branch_labels = None
depends_on = None


def upgrade():
    op.create_table('project_auto_actions',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('project_id', sa.Integer(), nullable=True),
        sa.Column('created_at', sa.DateTime(), nullable=True),
        sa.Column('updated_at', sa.DateTime(), nullable=True),
        sa.Column('created_by_id', sa.Integer(), nullable=True),
        sa.Column('group_id', sa.Integer(), nullable=True),
        sa.Column('on_events', postgresql.ARRAY(sa.String()), nullable=True),
        sa.Column('filter_condition', sa.String(), nullable=True),
        sa.Column('action_name', sa.String(), nullable=True),
        sa.Column('options', postgresql.JSONB(), nullable=True),
        sa.ForeignKeyConstraint(['created_by_id'], ['users.id'], ondelete='SET NULL'),
        sa.ForeignKeyConstraint(['project_id'], ['projects.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['group_id'], ['card_groups.id'], ondelete='CASCADE'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_project_auto_actions_project_id'), 'project_auto_actions', ['project_id'], unique=False)
    op.create_index(op.f('ix_project_auto_actions_project_id_group_id'), 'project_auto_actions', ['project_id', 'group_id'], unique=False)

    # actions on groups from contexts
    op.execute("""
        INSERT INTO project_auto_actions (project_id, created_at, updated_at, created_by_id, group_id, action_name, options)
        SELECT p.id, cga.created_at, cga.updated_at, cga.created_by_id, cga.group_id, cga.action_name, cga.options
        FROM card_group_actions cga
        JOIN card_groups cg ON cg.id = cga.group_id
        JOIN card_group_types cgt ON cgt.id = cg.group_type_id
        JOIN project_enabled_group_types pegt ON pegt.group_type_id = cgt.id
        JOIN projects p ON p.id = pegt.project_id
    """)

    # actions on groups from project attributes
    op.execute("""
        INSERT INTO project_auto_actions (project_id, created_at, updated_at, created_by_id, group_id, action_name, options)
        SELECT p.id, cga.created_at, cga.updated_at, cga.created_by_id, cga.group_id, cga.action_name, cga.options
        FROM card_group_actions cga
        JOIN card_groups cg ON cg.id = cga.group_id
        JOIN card_group_types cgt ON cgt.id = cg.group_type_id
        JOIN attributes a ON a.id = cgt.attribute_id
        JOIN projects p ON p.attribute_group_id = a.group_id
    """)

    # actions on groups from model attributes
    op.execute("""
        INSERT INTO project_auto_actions (project_id, created_at, updated_at, created_by_id, group_id, action_name, options)
        SELECT p.id, cga.created_at, cga.updated_at, cga.created_by_id, cga.group_id, cga.action_name, cga.options
        FROM card_group_actions cga
        JOIN card_groups cg ON cg.id = cga.group_id
        JOIN card_group_types cgt ON cgt.id = cg.group_type_id
        JOIN attributes a ON a.id = cgt.attribute_id
        JOIN card_models cm ON cm.attribute_group_id = a.group_id
        JOIN project_enabled_models pem ON pem.model_id = cm.id
        JOIN projects p ON p.id = pem.project_id
    """)

    op.execute("UPDATE card_groups SET cache_id = generate_cache_id(id)")

    op.execute("""
        UPDATE role_permissions SET actions = array_append(actions, 'MANAGE_AUTO_ACTIONS')
        FROM roles WHERE roles.id = role_permissions.role_id
        AND roles.builtin = 'ADMIN'
        AND role_permissions.object_type = 'project'
        AND role_permissions.object_id IS NULL
        AND NOT (role_permissions.actions @> '{"MANAGE_AUTO_ACTIONS"}'::varchar[])
    """)

    op.execute("""
        UPDATE roles SET cache_id = uuid_generate_v4()
        WHERE roles.id IN (
            SELECT DISTINCT roles.id
            FROM roles, role_permissions
            WHERE role_permissions.role_id = roles.id
            AND roles.builtin = 'ADMIN'
            AND role_permissions.object_type = 'project'
            AND role_permissions.object_id IS NULL
            AND (role_permissions.actions @> '{"MANAGE_AUTO_ACTIONS"}'::varchar[])
        )
    """)


def downgrade():
    op.drop_table('project_auto_actions')
