"""fix_roles_on_org_without_created_by_id

Revision: 0123
Revision ID: 51c94ea54825
Revises: 9e0835454e9
Create Date: 2018-04-10 10:05:07.799159

"""

# revision identifiers, used by Alembic.
revision = '51c94ea54825'
down_revision = '9e0835454e9'
branch_labels = None
depends_on = None

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


role_permissions = sa.Table(
    'role_permissions',
    sa.MetaData(),
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('role_id', sa.Integer(), nullable=True),
    sa.Column('project_id', sa.Integer(), nullable=True),
    sa.Column('object_type', sa.String(), nullable=True),
    sa.Column('object_id', sa.Integer(), nullable=True),
    sa.Column('actions', postgresql.ARRAY(sa.String()), nullable=False)
)


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

    # ADMIN
    r = conn.execute("""
        INSERT INTO roles (created_at, created_by_id, owner_id, name, description, builtin, cache_id)
        SELECT now(), o.created_by_id, o.id, 'Admin', 'Member who can manage project settings', 'ADMIN', uuid_generate_v4()
        FROM organizations o WHERE o.created_by_id IS NULL RETURNING id
    """)

    perms = []
    for r_info in r:
        role_id = r_info[0]
        perms.extend([
            {'role_id': role_id, 'object_type': 'project', 'actions': ['MANAGE_SUB_BOARDS','OPTIONS','ACCESS','MANAGE_ATTRIBUTES','MANAGE_SHARED_VIEWS','MANAGE_RECURRING']},
            {'role_id': role_id, 'object_type': 'card', 'actions': ['CREATE','EDIT','DELETE','SWITCH_MODEL','ARCHIVE']},
            {'role_id': role_id, 'object_type': 'card_model', 'actions': ['CREATE','EDIT','DELETE']},
            {'role_id': role_id, 'object_type': 'card_group_type', 'actions': ['CREATE','EDIT','DELETE']},
            {'role_id': role_id, 'object_type': 'card_log_type', 'actions': ['CREATE','EDIT','DELETE']},
            {'role_id': role_id, 'object_type': 'card_group', 'actions': ['CREATE','EDIT','MOVE_CARDS','DELETE']},
            {'role_id': role_id, 'object_type': 'request_form', 'actions': ['CREATE','EDIT','DELETE']},
            {'role_id': role_id, 'object_type': 'card_comment', 'actions': ['CREATE','EDIT','DELETE','DELETE_MINE']},
            {'role_id': role_id, 'object_type': 'card_log', 'actions': ['CREATE','EDIT','DELETE','DELETE_MINE']},
            {'role_id': role_id, 'object_type': 'attribute', 'actions': ['EDIT']}
        ])
    op.bulk_insert(role_permissions, perms)

    # MEMBER
    r = conn.execute("""
        INSERT INTO roles (created_at, created_by_id, owner_id, name, description, builtin, cache_id)
        SELECT now(), o.created_by_id, o.id, 'Member', 'Create, edit and collaborate with cards and groups', 'MEMBER', uuid_generate_v4()
        FROM organizations o WHERE o.created_by_id IS NULL RETURNING id
    """)
    perms = []
    for r_info in r:
        role_id = r_info[0]
        perms.extend([
            {'role_id': role_id, 'object_type': 'card', 'actions': ['CREATE','EDIT','DELETE','SWITCH_MODEL','ARCHIVE']},
            {'role_id': role_id, 'object_type': 'attribute', 'actions': ['EDIT']},
            {'role_id': role_id, 'object_type': 'card_group', 'actions': ['MOVE_CARDS']},
            {'role_id': role_id, 'object_type': 'card_comment', 'actions': ['CREATE','DELETE_MINE']},
            {'role_id': role_id, 'object_type': 'card_log', 'actions': ['CREATE','DELETE_MINE']}
        ])
    op.bulk_insert(role_permissions, perms)
    conn.execute("""
        UPDATE organizations o SET default_org_member_role_id = (SELECT id FROM roles WHERE owner_id = o.id AND builtin = 'MEMBER')
        WHERE o.created_by_id IS NULL
    """)

    # OBSERVER CAN COMMENT
    r = conn.execute("""
        INSERT INTO roles (created_at, created_by_id, owner_id, name, description, builtin, cache_id)
        SELECT now(), o.created_by_id, o.id, 'Observer allowed to comment', 'Read-only access but can comment on cards', 'OBSERVER ALLOWED TO COMMENT', uuid_generate_v4()
        FROM organizations o WHERE o.created_by_id IS NULL RETURNING id
    """)
    perms = []
    for r_info in r:
        role_id = r_info[0]
        perms.append({'role_id': role_id, 'object_type': 'card_comment', 'actions': ['CREATE','DELETE_MINE']})
    op.bulk_insert(role_permissions, perms)

    #OBSERVER
    r = conn.execute("""
        INSERT INTO roles (created_at, created_by_id, owner_id, name, description, builtin, cache_id)
        SELECT now(), o.created_by_id, o.id, 'Observer', 'Read-only access', 'OBSERVER', uuid_generate_v4()
        FROM organizations o WHERE o.created_by_id IS NULL RETURNING id
    """)

    # Set default org member role

    conn.execute("""UPDATE projects SET default_org_member_role_id = (
        SELECT id FROM roles WHERE owner_id = projects.owner_id AND builtin = 'ADMIN'
    ) FROM organizations o WHERE o.id = projects.owner_id AND o.created_by_id IS NULL AND projects.default_org_member_permission = 4""")

    conn.execute("""UPDATE projects SET default_org_member_role_id = (
        SELECT id FROM roles WHERE owner_id = projects.owner_id AND builtin = 'MEMBER'
    ) FROM organizations o WHERE o.id = projects.owner_id AND o.created_by_id IS NULL AND projects.default_org_member_permission = 3""")

    conn.execute("""UPDATE projects SET default_org_member_role_id = (
        SELECT id FROM roles WHERE owner_id = projects.owner_id AND builtin = 'OBSERVER ALLOWED TO COMMENT'
    ) FROM organizations o WHERE o.id = projects.owner_id AND o.created_by_id IS NULL AND projects.default_org_member_permission = 2""")

    conn.execute("""UPDATE projects SET default_org_member_role_id = (
        SELECT id FROM roles WHERE owner_id = projects.owner_id AND builtin = 'OBSERVER'
    ) FROM organizations o WHERE o.id = projects.owner_id AND o.created_by_id IS NULL AND projects.default_org_member_permission = 1""")

    # update member roles

    conn.execute("""UPDATE project_members SET role_id = (
        SELECT roles.id FROM roles, projects WHERE project_members.project_id = projects.id
        AND roles.owner_id = projects.owner_id AND roles.builtin = 'ADMIN'
    ) FROM organizations o, projects p WHERE p.id = project_members.project_id AND o.id = p.owner_id AND o.created_by_id IS NULL AND project_members.permission = 4""")

    conn.execute("""UPDATE project_members SET role_id = (
        SELECT roles.id FROM roles, projects WHERE project_members.project_id = projects.id
        AND roles.owner_id = projects.owner_id AND roles.builtin = 'MEMBER'
    ) FROM organizations o, projects p WHERE p.id = project_members.project_id AND o.id = p.owner_id AND o.created_by_id IS NULL AND project_members.permission = 3""")

    conn.execute("""UPDATE project_members SET role_id = (
        SELECT roles.id FROM roles, projects WHERE project_members.project_id = projects.id
        AND roles.owner_id = projects.owner_id AND roles.builtin = 'OBSERVER ALLOWED TO COMMENT'
    ) FROM organizations o, projects p WHERE p.id = project_members.project_id AND o.id = p.owner_id AND o.created_by_id IS NULL AND project_members.permission = 2""")

    conn.execute("""UPDATE project_members SET role_id = (
        SELECT roles.id FROM roles, projects WHERE project_members.project_id = projects.id
        AND roles.owner_id = projects.owner_id AND roles.builtin = 'OBSERVER'
    ) FROM organizations o, projects p WHERE p.id = project_members.project_id AND o.id = p.owner_id AND o.created_by_id IS NULL AND project_members.permission = 1""")

    conn.execute('UPDATE organizations SET cache_id = uuid_generate_v4() WHERE created_by_id IS NULL')
    conn.execute('UPDATE projects SET members_cache_id = uuid_generate_v4() FROM organizations o WHERE o.id = projects.owner_id AND o.created_by_id IS NULL')


def downgrade():
    pass
