"""add_reminders

Revision: 0141
Revision ID: 1d830ee99d4c
Revises: 25ae23668316
Create Date: 2018-05-09 15:14:15.912273

"""

# revision identifiers, used by Alembic.
revision = '1d830ee99d4c'
down_revision = '25ae23668316'
branch_labels = None
depends_on = None

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

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

    reminders = op.create_table('reminders',
        sa.Column('id', sa.Integer(), nullable=False),
        sa.Column('created_at', sa.DateTime(), nullable=True),
        sa.Column('created_by_id', sa.Integer(), nullable=True),
        sa.Column('card_id', sa.Integer(), nullable=True),
        sa.Column('targets', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
        sa.Column('reminding_date', sa.DateTime(), nullable=True),
        sa.Column('attribute_id', sa.Integer(), nullable=True),
        sa.Column('cache_id', sa.String(), nullable=True),
        sa.ForeignKeyConstraint(['card_id'], ['cards.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['attribute_id'], ['attributes.id'], ondelete='CASCADE'),
        sa.ForeignKeyConstraint(['created_by_id'], ['users.id'], ondelete='SET NULL'),
        sa.PrimaryKeyConstraint('id')
    )

    r_infos = conn.execute("""
        SELECT c.id, a.attribute_id, a.value->'end' "end", a.created_at, a.created_by_id
        FROM cards c
        JOIN card_attributes a ON a.card_id = c.id
        WHERE a.type_name = 'date'
            AND a.value is NOT NULL
            AND (a.value->'end')::text != 'null'
            AND to_timestamp(substring((a.value->'end')::text from 2 for 10), 'YYYY-MM-DD') >= now() + INTERVAL '1 day'
    """)

    to_insert = []
    for r in r_infos:
        date = r[2]
        if len(date) == 10:
            date += ' 00:00:00'
        to_insert.append({
            'created_at': r[3],
            'created_by_id': r[4],
            'card_id': r[0],
            'targets': ['subscribers'],
            'reminding_date': datetime.datetime.strptime(date[:19], '%Y-%m-%d %H:%M:%S') - datetime.timedelta(days=1),
            'attribute_id': r[1],
            'cache_id': uuid.uuid4()
        })
    op.bulk_insert(reminders, to_insert)

    op.execute("""
        UPDATE role_permissions SET actions = array_append(actions, 'MANAGE_REMINDERS')
        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_REMINDERS"}'::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_REMINDERS"}'::varchar[])
        )
    """)

    op.execute("""
        UPDATE projects SET members_cache_id = uuid_generate_v4()
    """)

    op.add_column('projects', sa.Column('send_emails', sa.Boolean(), nullable=True, server_default="True"))

def downgrade():
    op.drop_column('projects', 'send_emails')
    op.drop_table('reminders')
