# -*- 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

from xivo_agid import dialplan_variables
from xivo_agid.modules.xds_routing import _get_mds_main_address, _get_mds_address, _get_mds_from_peer_secret, \
    _xds_routing


class TestXDSRouting(unittest.TestCase):

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

    def side_effect(arg, cursor):
        values = {'1001': ('mds1', '10.0.1.10'),
                  '1002': ('mds2', '10.0.1.20'),
                  '1003': ('mds1', '10.0.1.10'),
                  '1004': ('mds1', '10.0.1.10'),
                  'mds1': 'secret'}
        return values[arg]

    @patch("psycopg2.connect")
    def test_get_mds_address(self, mock_connect):
        expected = {"linefeatures.configregistrar": "mds2", "mediaserver.voip_ip": "10.0.1.10"}

        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', mock_cursor), ('mds2', '10.0.1.10'))

    @patch("psycopg2.connect")
    def test_get_mds_main_address(self, mock_connect):
        expected = {"netiface.address": "10.0.1.10"}

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

        self.assertEqual(_get_mds_main_address(mock_cursor), '10.0.1.10')

    @patch("psycopg2.connect")
    def test_get_mds_from_peer_secret(self, mock_connect):
        expected = {"usersip.secret": "secret"}

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

        self.assertEqual(_get_mds_from_peer_secret('mds1', mock_cursor), 'secret')

    @patch("xivo_agid.modules.xds_routing._get_mds_address", side_effect=side_effect)
    @patch("xivo_agid.modules.xds_routing._get_mds_from_peer_secret", side_effect=side_effect)
    def test_xds_routing_on_different_mds(self, mock_get_mds_address, mock_get_mds_from_peer_secret):
        expected = [call(dialplan_variables.XDS_FROMPEER, 'mds1'),
                    call(dialplan_variables.XDS_CALLEDNUMBER, '1002'),
                    call(dialplan_variables.XDS_FROMPEERSECRET, 'secret'),
                    call(dialplan_variables.XDS_DST_IP, '10.0.1.20')]

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

        _xds_routing(self._agi, self._cursor, self._args)
        self.assertEqual(self._agi.set_variable.call_args_list, expected)

    @patch("xivo_agid.modules.xds_routing._get_mds_address", side_effect=side_effect)
    @patch("xivo_agid.modules.xds_routing._get_mds_from_peer_secret", side_effect=side_effect)
    def test_xds_routing_on_same_mds(self, mock_get_mds_address, mock_get_mds_from_peer_secret):
        self._agi.get_variable.side_effect = \
            lambda x: {dialplan_variables.DESTINATION_NUMBER: '1004',
                       dialplan_variables.SRCNUM: '1003',
                       dialplan_variables.BASE_EXTEN: '1004',
                       dialplan_variables.SIPDOMAIN: '10.0.1.10'}.get(x, '')

        _xds_routing(self._agi, self._cursor, self._args)
        self.assertItemsEqual(self._agi.set_variable.call_args_list, [])
