# -*- 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 unittest
from mock import Mock, patch, call
import os

from xivo_agid import dialplan_variables
from xivo_agid.modules.xds_routing import _get_mds_address, _xds_routing


class TestXDSRouting(unittest.TestCase):

    def setUp(self):
        self._agi = Mock()
        self._cursor = Mock()
        self._args = Mock()

    def side_effect_address(arg, exten_context, cursor):
        values = {'1001': 'mds1',
                  '1002': 'mds2',
                  '1003': 'mds1',
                  '1004': 'mds1'}
        return values[arg]

    @patch("psycopg2.connect")
    def test_get_mds_address(self, mock_connect):
        expected = {"mediaserver.name": "mds2"}
        context = 'default'

        mock_con = mock_connect.return_value
        mock_cursor = mock_con.cursor.return_value
        mock_cursor.fetchone.return_value = expected

        self.assertEqual(_get_mds_address('1001', context, mock_cursor), 'mds2')

    @patch("psycopg2.connect")
    def test_get_mds_address_with_unknown_registrar(self, mock_connect):
        expected = {"mediaserver.name": "unknownMDS"}
        context = 'default'

        mock_con = mock_connect.return_value
        mock_cursor = mock_con.cursor.return_value
        mock_cursor.fetchone.return_value = None

        with self.assertRaises(LookupError) as error:
            _get_mds_address('1005', context, mock_cursor)

    @patch.dict(os.environ, {'MDS_NAME': 'mds1'})
    @patch("xivo_agid.modules.xds_routing._get_mds_address", side_effect=side_effect_address)
    def test_xds_routing_on_different_mds(self, mock_get_mds_address):
        expected = [call(dialplan_variables.XDS_PEER, 'mds2'),
                    call(dialplan_variables.XDS_CALLEDNUMBER, '1002')]

        self._agi.get_variable.side_effect = \
            lambda x: {dialplan_variables.EXTEN: '1002',
                       dialplan_variables.DESTINATION_NUMBER: '1002',
                       dialplan_variables.SRCNUM: '1001',
                       dialplan_variables.BASE_EXTEN: '1002',
                       dialplan_variables.SIPDOMAIN: '10.0.1.10',
                       dialplan_variables.BASE_CONTEXT: 'default'}.get(x, '')

        _xds_routing(self._agi, self._cursor, self._args)

        self.assertEqual(self._agi.set_variable.call_args_list, expected)
        mock_get_mds_address.assert_called_with('1002', 'default', self._cursor)

    @patch.dict(os.environ, {'MDS_NAME': 'mds1'})
    @patch("xivo_agid.modules.xds_routing._get_mds_address", side_effect=side_effect_address)
    def test_xds_routing_on_different_mds_different_context(self, mock_get_mds_address):
        expected = [call(dialplan_variables.XDS_PEER, 'mds2'),
                    call(dialplan_variables.XDS_CALLEDNUMBER, '1002')]

        self._agi.get_variable.side_effect = \
            lambda x: {dialplan_variables.EXTEN: '1002',
                       dialplan_variables.DESTINATION_NUMBER: '1002',
                       dialplan_variables.SRCNUM: '1001',
                       dialplan_variables.BASE_EXTEN: '1002',
                       dialplan_variables.SIPDOMAIN: '10.0.1.10',
                       dialplan_variables.XDS_CONTEXT: 'site-main'}.get(x, '')

        _xds_routing(self._agi, self._cursor, self._args)

        self.assertEqual(self._agi.set_variable.call_args_list, expected)
        mock_get_mds_address.assert_called_with('1002', 'site-main', self._cursor)
