# -*- coding: utf-8 -*-

# Copyright (C) 2018 Avencall
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>

import logging
import os

from xivo_agid import agid, dialplan_variables

logger = logging.getLogger(__name__)

MDS_CONFIGREGISTRAR_COLNAME = "linefeatures.configregistrar"
MDS_CONFIGREGISTRARIP_COLNAME = "all_mediaserver.voip_ip"
MDS_TRUNK_SECRET_COLNAME = "usersip.secret"


def _get_dialplan_variables(cursor, agi):
    dstnum = agi.get_variable(dialplan_variables.EXTEN)
    exten_context = agi.get_variable(dialplan_variables.BASE_CONTEXT)
    xds_context = agi.get_variable(dialplan_variables.XDS_CONTEXT)
    mds_from_peer_name = os.getenv('MDS_NAME', 'default')

    context = xds_context if xds_context else exten_context

    line_registrar, media_server_ip = _get_mds_address(dstnum, context, cursor)
    mds_from_peer_secret = _get_mds_from_peer_secret(mds_from_peer_name, cursor)

    return {
        'mds_from_peer': mds_from_peer_name,
        'mds_called_number': dstnum,
        'mds_from_peer_secret': mds_from_peer_secret,
        'mds_dst_ip': media_server_ip
    }


def _set_dialplan_variables(agi, dial_string_variables):
    agi.set_variable(dialplan_variables.XDS_FROMPEER, dial_string_variables['mds_from_peer'])
    agi.set_variable(dialplan_variables.XDS_CALLEDNUMBER, dial_string_variables['mds_called_number'])
    agi.set_variable(dialplan_variables.XDS_FROMPEERSECRET, dial_string_variables['mds_from_peer_secret'])
    agi.set_variable(dialplan_variables.XDS_DST_IP, dial_string_variables['mds_dst_ip'])


def _get_mds_address(dstnum, exten_context, cursor):
    cursor.query("SELECT ${columns} FROM linefeatures "
                 "LEFT JOIN all_mediaserver "
                 "ON linefeatures.configregistrar = all_mediaserver.name "
                 "WHERE linefeatures.number = %s AND linefeatures.context = %s",
                 (MDS_CONFIGREGISTRAR_COLNAME, MDS_CONFIGREGISTRARIP_COLNAME,),
                 (dstnum, exten_context))
    try:
        res = cursor.fetchone()
        config_registrar = res[MDS_CONFIGREGISTRAR_COLNAME]
        config_registrar_ip = res[MDS_CONFIGREGISTRARIP_COLNAME]
    except Exception, e:
        raise LookupError('Unable to get mds address for destination: %s. %s' % (dstnum, e))
    else:
        return config_registrar, config_registrar_ip


def _get_mds_from_peer_secret(name, cursor):
    cursor.query("SELECT ${columns} FROM usersip "
                 "WHERE name = %s",
                 (MDS_TRUNK_SECRET_COLNAME,),
                 (name,))
    try:
        res = cursor.fetchone()
        trunk_secret = res[MDS_TRUNK_SECRET_COLNAME]
    except Exception, e:
        raise LookupError('Unable to get mds secret for server: %s. %s' % (name, e))
    else:
        return trunk_secret


def _xds_routing(agi, cursor, args):
    dial_string_variables = _get_dialplan_variables(cursor, agi)
    _set_dialplan_variables(agi, dial_string_variables)


def xds_routing(agi, cursor, args):
    try:
        _xds_routing(agi, cursor, args)
    except Exception, e:
        logger.error('Error during xds routing: %s', e)
        agi.dp_break(e)


agid.register(xds_routing)
