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

from ConfigParser import NoOptionError, NoSectionError

from mock import Mock, patch

from xivo_confgen.asterisk import AsteriskFrontend
from xivo_dao.alchemy.agentfeatures import AgentFeatures

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_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)

    def test_encoding(self):
        charset = ("ascii", "US-ASCII",)
        self.assertTrue(sys.getdefaultencoding() in charset, "Test should be run in ascii, in eclipse change run configuration common tab")

    def test_gen_iax_trunk(self):
        trunk = {
            'id': 1,
            'name': u'xivo_devel_51',
            'type': u'friend',
            'username': u'xivo_devel_51',
            'secret': u'xivo_devel_51',
            'dbsecret': u'',
            'context': u'default',
            'language': u'fr_FR',
            'accountcode': None,
            'amaflags': None,
            'mailbox': None,
            'callerid': None,
            'fullname': None,
            'cid_number': None,
            'trunk': 0,
            'auth': u'plaintext,md5',
            'encryption': None,
            'forceencryption': None,
            'maxauthreq': None,
            'inkeys': None,
            'outkey': None,
            'adsi': None,
            'transfer': None,
            'codecpriority': None,
            'jitterbuffer': None,
            'forcejitterbuffer': None,
            'sendani': 0,
            'qualify': u'no',
            'qualifysmoothing': 0,
            'qualifyfreqok': 60000,
            'qualifyfreqnotok': 10000,
            'timezone': None,
            'disallow': None,
            'allow': None,
            'mohinterpret': None,
            'mohsuggest': None,
            'deny': None,
            'permit': None,
            'defaultip': None,
            'sourceaddress': None,
            'setvar': u'',
            'host': u'192.168.32.253',
            'port': 4569,
            'mask': None,
            'regexten': None,
            'peercontext': None,
            'ipaddr': u'',
            'regseconds': 0,
            'immediate': None,
            'parkinglot': None,
            'protocol': u'iax',
            'category': u'trunk',
            'commented': 0,
            'requirecalltoken': u'auto',
        }

        result = self.asteriskFrontEnd._gen_iax_trunk(trunk)

        self.assertTrue(u'[xivo_devel_51]' in result)
        self.assertTrue(u'regseconds =  0' in result)
        self.assertTrue(u'qualifysmoothing =  0' in result)
        self.assertTrue(u'secret =  xivo_devel_51' in result)
        self.assertTrue(u'type =  friend' in result)
        self.assertTrue(u'username =  xivo_devel_51' in result)
        self.assertTrue(u'auth =  plaintext,md5' in result)
        self.assertTrue(u'qualifyfreqnotok =  10000' in result)
        self.assertTrue(u'requirecalltoken =  auto' in result)
        self.assertTrue(u'port =  4569' in result)
        self.assertTrue(u'context =  default' in result)
        self.assertTrue(u'sendani =  0' in result)
        self.assertTrue(u'qualify =  no' in result)
        self.assertTrue(u'trunk =  0' in result)
        self.assertTrue(u'language =  fr_FR' in result)
        self.assertTrue(u'host =  192.168.32.253' in result)
        self.assertTrue(u'qualifyfreqok =  60000' in result)

    def test_gen_iax_conf_general(self):
        staticiax = [
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'bindport', 'var_val': u'4569'},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'bindaddr', 'var_val': u'0.0.0.0'},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'iaxcompat', 'var_val': u'no'},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'authdebug', 'var_val': u'yes'},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'srvlookup', 'var_val': None},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'shrinkcallerid', 'var_val': None},
            {'filename': u'iax.conf', 'category': u'general', 'var_name': u'language', 'var_val': u'fr_FR'},
        ]

        result = self.asteriskFrontEnd._gen_iax_general(staticiax)

        self.assertTrue(u'[general]' in result)
        self.assertTrue(u'bindport = 4569' in result)
        self.assertTrue(u'bindaddr = 0.0.0.0' in result)
        self.assertTrue(u'iaxcompat = no' in result)
        self.assertTrue(u'authdebug = yes' in result)
        self.assertTrue(u'language = fr_FR' in result)

    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)
