"""remove outgoing call destination

Revision ID: 29331e1f8340
Revises: 47a376ec3048

"""

# revision identifiers, used by Alembic.
revision = '29331e1f8340'
down_revision = '47a376ec3048'

from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql.expression import cast
from sqlalchemy.types import Integer


dialaction_table = sa.sql.table('dialaction',
                                sa.sql.column('event'),
                                sa.sql.column('category'),
                                sa.sql.column('categoryval'),
                                sa.sql.column('action'),
                                sa.sql.column('actionarg1'),
                                sa.sql.column('actionarg2'))

dialaction_category = ('callfilter',
                       'group',
                       'incall',
                       'queue',
                       'user')

schedule_table = sa.sql.table('schedule',
                              sa.sql.column('id'),
                              sa.sql.column('name'),
                              sa.sql.column('fallback_action'),
                              sa.sql.column('fallback_actionid'),
                              sa.sql.column('fallback_actionargs'))

outcall_table = sa.sql.table('outcall',
                              sa.sql.column('id'),
                              sa.sql.column('name'),
                              sa.sql.column('context'))

def remove_outcalls_from_dialaction(category):
    op.execute(dialaction_table
               .update()
               .values(action='none',
                       actionarg1='',
                       actionarg2='')
               .where(sa.sql.and_(
                      dialaction_table.c.category == category,
                      dialaction_table.c.action == 'outcall')))

def remove_outcalls_from_schedule():
    op.execute(schedule_table
               .update()
               .values(fallback_action='none',
                       fallback_actionid='',
                       fallback_actionargs='')
               .where(schedule_table.c.fallback_action == 'outcall'))

def print_other(table_name, category, name):
    other_table = sa.sql.table(table_name,
                         sa.sql.column('id'),
                         sa.sql.column(name),
                         sa.sql.column('lastname'))

    join_conditions = (dialaction_table
                       .join(other_table,
                             cast(dialaction_table.c.categoryval, Integer) == other_table.c.id))

    if (category == 'user'):
        selected_columns = [dialaction_table.c.actionarg1,
                            dialaction_table.c.actionarg2,
                            other_table.c[name],
                            other_table.c.id,
                            dialaction_table.c.event,
                            other_table.c['lastname']]
    else:
        selected_columns = [dialaction_table.c.actionarg1,
                            dialaction_table.c.actionarg2,
                            other_table.c[name],
                            other_table.c.id,
                            dialaction_table.c.event]

    query = (sa.sql.select(selected_columns,
                           from_obj=[join_conditions])
             .where(sa.sql.and_(
                    dialaction_table.c.category == category,
                    dialaction_table.c.action == 'outcall'))
             .order_by(sa.sql.column(name).asc()))

    rows = op.get_bind().execute(query)

    for row in rows:
        print_row({
            'outcall_id': row.actionarg1,
            'outcall_number': row.actionarg2,
            'object_name': row[name],
            'object_id': row.id,
            'event': row.event,
            'object_lastname': row['lastname'] if row.has_key('lastname') else None,
            'category': category
            })

def print_schedules():
    query = (sa.sql.select([schedule_table.c.fallback_actionid,
                            schedule_table.c.fallback_actionargs,
                            schedule_table.c.name,
                            schedule_table.c.id])
             .where(schedule_table.c.fallback_action == 'outcall'))

    rows = op.get_bind().execute(query)

    for row in rows:
        print_row({
            'outcall_id': row.fallback_actionid,
            'outcall_number': row.fallback_actionargs,
            'object_name': row.name,
            'object_id': row.id,
            'event': 'out of schedule',
            'object_lastname': None,
            'category': 'schedule'
            })

def print_row(data):
    details_row = get_outcall_details(data['outcall_id'])

    if (data['object_lastname']):
        full_name = u"{} {}".format(data['object_name'], data['object_lastname'])
    else:
        full_name = data['object_name']

    if (details_row != None):
        outcall_name, outcall_context = details_row.name, details_row.context
    else:
        print (u'[MIGRATE_OUTCALL_FWD] : Removing redirection towards nonexistent(!) outgoing call '
               u'from {} "{}" (ID {}) in "{}" destination'
               .format(data['category'], full_name, data['object_id'], data['event']))
        return

    if (data['outcall_number']):
        outcall_contact = u'{}" to number "{}'.format(outcall_name, data['outcall_number'])
    else:
        outcall_contact = u'{}'.format(outcall_name)

    print (u'[MIGRATE_OUTCALL_FWD] : Removing redirection towards outgoing call "{}" (@{}) '
           u'from {} "{}" (ID {}) in "{}" destination'
           .format(outcall_contact, outcall_context,
                   data['category'], full_name, data['object_id'], data['event']))

def get_outcall_details(id):
    query = (sa.sql.select([outcall_table.c.name, outcall_table.c.context])
             .where(outcall_table.c.id == id))

    rows = op.get_bind().execute(query)
    row = rows.fetchone()

    return row


def upgrade():
    print_schedules()

    print_other(table_name='incall',
                category='incall',
                name='exten')

    print_other(table_name='groupfeatures',
                category='group',
                name='name')

    print_other(table_name='userfeatures',
                category='user',
                name='firstname')

    print_other(table_name='queuefeatures',
                category='queue',
                name='name')

    print_other(table_name='callfilter',
                category='callfilter',
                name='name')

    for category in dialaction_category:
        remove_outcalls_from_dialaction(category)
    remove_outcalls_from_schedule()


def downgrade():
    pass
