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

# Copyright (C) 2011-2016 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 configparser import NoOptionError, NoSectionError

from mock import Mock, patch
from xivo_dao.alchemy.agentfeatures import AgentFeatures

from xivo_confgen.asterisk import AsteriskFrontend


class Test(unittest.TestCase):

    def setUp(self):
        self._config = Mock()
        self.asteriskFrontEnd = AsteriskFrontend(self._config)

    def test_nova_compat_not_defined(self):
        def my_get_boolean(x, y):
            if x == 'asterisk':
                if y == 'nova_compatibility':
                    raise NoOptionError('section', 'option')
            else:
                return True

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertFalse(asterisk_frontend._nova_compatibility)

    def test_stun_enable_not_defined_default_to_false(self):
        def my_get_boolean(x, y):
            if x == 'asterisk':
                if y == 'stun_enable':
                    raise NoOptionError('section', 'option')
            else:
                return True

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertFalse(asterisk_frontend._stun_enable)

    def test_turn_enable_not_defined_default_to_true(self):
        def my_get_boolean(x, y):
            if x == 'asterisk':
                if y == 'turn_enable':
                    raise NoOptionError('section', 'option')
            else:
                return True

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertTrue(asterisk_frontend._turn_enable)

    def test_mds_config_section_not_defined(self):
        def my_get_boolean(x, y):
            if x == 'mds':
                raise NoSectionError('section')
            else:
                return ''

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertFalse(asterisk_frontend._mds)

    def test_mds_config_section_defined_parameter_missing(self):
        def my_get_boolean(x, y):
            if x == 'mds':
                if y == 'mds_mode':
                    raise NoOptionError('section', 'option')
            else:
                return ''

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertFalse(asterisk_frontend._mds)

    def test_mds_config_section_defined_with_parameter(self):
        mode = 'yes'

        def my_get_boolean(x, y):
            if x == 'mds':
                if y == 'mds_mode':
                    return mode
            else:
                return ''

        config = Mock()
        config.getboolean.side_effect = my_get_boolean

        asterisk_frontend = AsteriskFrontend(config)

        self.assertEquals(asterisk_frontend._mds, mode)

    agent1 = AgentFeatures()
    agent1.id = 1
    agent1.number = 1001
    agent2 = AgentFeatures()
    agent2.id = 2
    agent2.number = 1002
    agents = [agent1, agent2]

    @patch('xivo_dao.agent_dao.all', Mock(return_value=agents))
    @patch('xivo_dao.asterisk_conf_dao.find_agent_queue_skills_settings', Mock(return_value=[]))
    def test_gen_queue_skills_conf_without_skills(self):
        self.asteriskFrontEnd._mds = False
        result = self.asteriskFrontEnd.queueskills_conf()
        expected = \
            '\n[agent-1]' \
            '\nagent_1 = 100' \
            '\nagent_no_1001 = 100' \
            '\ngenagent = 100' \
            '\n' \
            '\n[agent-2]' \
            '\nagent_2 = 100' \
            '\nagent_no_1002 = 100' \
            '\ngenagent = 100\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.agent_dao.all', Mock(return_value=agents))
    @patch('xivo_dao.asterisk_conf_dao.find_agent_queue_skills_settings',
           Mock(return_value=[{'id': 1, 'name': 'english', 'weight': 75},
                              {'id': 2, 'name': 'english', 'weight': 50},
                              {'id': 1, 'name': 'french', 'weight': 25}]))
    def test_gen_queue_skills_conf_with_skills(self):
        self.asteriskFrontEnd._mds = False
        result = self.asteriskFrontEnd.queueskills_conf()
        expected = \
            '\n[agent-1]' \
            '\nagent_1 = 100' \
            '\nagent_no_1001 = 100' \
            '\ngenagent = 100' \
            '\nenglish = 75' \
            '\nfrench = 25' \
            '\n' \
            '\n[agent-2]' \
            '\nagent_2 = 100' \
            '\nagent_no_1002 = 100' \
            '\ngenagent = 100' \
            '\nenglish = 50\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.agent_dao.all', Mock(return_value=agents))
    @patch('xivo_dao.asterisk_conf_dao.find_agent_queue_skills_settings',
           Mock(return_value=[{'id': 1, 'name': 'english', 'weight': 75},
                              {'id': 2, 'name': 'english', 'weight': 50},
                              {'id': 1, 'name': 'french', 'weight': 25}]))
    def test_gen_queue_skills_conf_with_skills_with_mds(self):
        self.asteriskFrontEnd._mds = {'peername': 'mds'}

        result = self.asteriskFrontEnd.queueskills_conf()
        expected = '\n;Queue skills void for MDS\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_queue_skillrule_settings',
           Mock(return_value=[{'name': 'select_agent', 'rule': '$agent > 0'}]))
    def test_gen_queue_skills_rule(self):
        self.asteriskFrontEnd._mds = False
        result = self.asteriskFrontEnd.queueskillrules_conf()
        expected = \
            '\n[select_agent]' \
            '\nrule = $agent > 0\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_queue_skillrule_settings',
           Mock(return_value=[{'name': 'select_agent', 'rule': '$agent > 0'}]))
    def test_gen_queue_skills_rule_with_mds(self):
        self.asteriskFrontEnd._mds = {'peername': 'mds'}
        result = self.asteriskFrontEnd.queueskillrules_conf()
        expected = '\n;Queue Skill Rules void for MDS\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_meetme_general_settings',
           Mock(return_value=[{'var_name': 'audiobuffers', 'var_val': '32'},
                              {'var_name': 'schedule', 'var_val': 'yes'}]))
    @patch('xivo_dao.asterisk_conf_dao.find_meetme_rooms_settings',
           Mock(return_value=[{'var_name': 'conf', 'var_val': '8001,8001'}, ]))
    def test_gen_meetme(self):
        self.asteriskFrontEnd._mds = False
        result = self.asteriskFrontEnd.meetme_conf()
        expected = \
            '\n[general]' \
            '\naudiobuffers = 32' \
            '\nschedule = yes' \
            '\n' \
            '\n[rooms]' \
            '\nconf = 8001,8001\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_meetme_general_settings',
           Mock(return_value=[{'var_name': 'audiobuffers', 'var_val': '32'},
                              {'var_name': 'schedule', 'var_val': 'yes'}]))
    @patch('xivo_dao.asterisk_conf_dao.find_meetme_rooms_settings',
           Mock(return_value=[{'var_name': 'conf', 'var_val': '8001,8001'}, ]))
    def test_gen_meetme_with_mds(self):
        self.asteriskFrontEnd._mds = {'peername': 'mds'}
        result = self.asteriskFrontEnd.meetme_conf()
        expected = \
            '\n;Meetme void on MDS' \
            '\n[general]' \
            '\n' \
            '\n[rooms]\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_meetme_general_settings',
           Mock(return_value=[{'var_name': 'audiobuffers', 'var_val': '32'},
                              {'var_name': 'schedule', 'var_val': 'yes'}]))
    @patch('xivo_dao.asterisk_conf_dao.find_meetme_rooms_settings',
           Mock(return_value=[{'var_name': 'conf', 'var_val': '8001,8001'}, ]))
    def test_gen_queues(self):
        self.asteriskFrontEnd._mds = False
        result = self.asteriskFrontEnd.meetme_conf()
        expected = \
            '\n[general]' \
            '\naudiobuffers = 32' \
            '\nschedule = yes' \
            '\n' \
            '\n[rooms]' \
            '\nconf = 8001,8001\n'

        self.assertEquals(result, expected)

    @patch('xivo_dao.asterisk_conf_dao.find_sip_general_settings',
           Mock(return_value=[{'filename': u'sip.conf', 'category': u'general', 'var_name': u'stunaddr',
                               'var_val': u'stun.l.google.com:19302'}]))
    def test_gen_rtp(self):
        self.asteriskFrontEnd._mds = False
        self.asteriskFrontEnd._stun_enable = True
        self.asteriskFrontEnd._turn_enable = True
        result = self.asteriskFrontEnd.rtp_conf()
        expected = \
            'rtpstart = 10000' \
            '\nrtpend = 20000' \
            '\nicesupport = yes' \
            '\nstunaddr = stun.l.google.com:19302' \
            '\nturnaddr = stun.l.google.com:19302' \
            '\n'

        self.assertEquals(result, expected)
