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

# Copyright (C) 2010-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/>


from configparser import NoOptionError, NoSectionError
from io import StringIO

from xivo_dao import asterisk_conf_dao, line_dao, agent_dao
from xivo_dao.resources.endpoint_sip import dao as sip_dao

from xivo_confgen.generators.extensionsconf import ExtensionsConf
from xivo_confgen.generators.features import FeaturesConf
from xivo_confgen.generators.queues import QueuesConf
from xivo_confgen.generators.res_parking import ResParkingConf
from xivo_confgen.generators.rtp import RtpConf
from xivo_confgen.generators.sip import SipConf
from xivo_confgen.generators.sip_mds_trunk import SipMdsTrunkGenerator
from xivo_confgen.generators.sip_trunk import SipTrunkGenerator
from xivo_confgen.generators.sip_user import SipUserGenerator
from xivo_confgen.generators.pjsip import PjsipConf
from xivo_confgen.generators.sccp import SccpConf
from xivo_confgen.generators.voicemail import VoicemailConf, VoicemailGenerator
from xivo_confgen.hints.generator import HintGenerator


class AsteriskFrontend(object):

    def __init__(self, config):
        self.contextsconf = config.get('asterisk', 'contextsconf')

        try:
            self._stun_enable = config.getboolean('asterisk', 'stun_enable')
        except NoOptionError:
            self._stun_enable = False

        try:
            self._turn_enable = config.getboolean('asterisk', 'turn_enable')
        except NoOptionError:
            self._turn_enable = True

        try:
            self._nova_compatibility = config.getboolean('asterisk', 'nova_compatibility')
        except NoOptionError:
            self._nova_compatibility = False

        try:
            self._mds = config.getboolean('mds', 'mds_mode')
        except (NoSectionError, NoOptionError) as e:
            self._mds = False

    def features_conf(self):
        config_generator = FeaturesConf()
        return self._generate_conf_from_generator(config_generator)

    def res_parking_conf(self):
        config_generator = ResParkingConf()
        return self._generate_conf_from_generator(config_generator)

    def sccp_conf(self):
        config_generator = SccpConf(nova_compatibility=self._nova_compatibility)
        return self._generate_conf_from_generator(config_generator)

    def sip_conf(self):
        trunk_generator = SipTrunkGenerator(asterisk_conf_dao, sip_dao)
        user_generator = SipUserGenerator(asterisk_conf_dao, line_dao, nova_compatibility=self._nova_compatibility)
        mds_trunk_generator = SipMdsTrunkGenerator(asterisk_conf_dao)
        config_generator = SipConf(trunk_generator, user_generator, mds_trunk_generator)
        return self._generate_conf_from_generator(config_generator)

    def pjsip_conf(self):
        config_generator = PjsipConf(self._nova_compatibility)
        return self._generate_conf_from_generator(config_generator)

    def voicemail_conf(self):
        voicemail_generator = VoicemailGenerator.build()
        config_generator = VoicemailConf(voicemail_generator)
        return self._generate_conf_from_generator(config_generator)

    def extensions_conf(self):
        hint_generator = HintGenerator.build()
        config_generator = ExtensionsConf(self.contextsconf, hint_generator)
        return self._generate_conf_from_generator(config_generator)

    def queues_conf(self):
        config_generator = QueuesConf(mds=self._mds)
        return self._generate_conf_from_generator(config_generator)

    def _generate_conf_from_generator(self, config_generator):
        output = StringIO()
        config_generator.generate(output)
        return output.getvalue()

    def meetme_conf(self):
        options = StringIO()

        if self._mds:
            print('\n;Meetme void on MDS', file=options)
            print('[general]', file=options)
            print('\n[rooms]', file=options)
        else:
            print('\n[general]', file=options)

            for c in asterisk_conf_dao.find_meetme_general_settings():
                print("%s = %s" % (c['var_name'], c['var_val']), file=options)

            print('\n[rooms]', file=options)
            for r in asterisk_conf_dao.find_meetme_rooms_settings():
                print("%s = %s" % (r['var_name'], r['var_val']), file=options)

        return options.getvalue()

    def musiconhold_conf(self):
        options = StringIO()

        cat = None
        for m in asterisk_conf_dao.find_musiconhold_settings():
            if m['var_val'] is None:
                continue

            if m['category'] != cat:
                cat = m['category']
                print('\n[%s]' % cat, file=options)

            print("%s = %s" % (m['var_name'], m['var_val']), file=options)

        return options.getvalue()

    def queueskills_conf(self):
        """Generate queueskills.conf asterisk configuration file
        """
        options = StringIO()

        if self._mds:
            print('\n;Queue skills void for MDS', file=options)
        else:
            skills = asterisk_conf_dao.find_agent_queue_skills_settings()
            for a in agent_dao.all():
                print("\n[agent-%d]" % a.id, file=options)
                print("agent_%d = 100" % a.id, file=options)
                print("agent_no_%s = 100" % a.number, file=options)
                print("genagent = 100", file=options)
                for sk in skills:
                    if sk['id'] == a.id:
                        print("%s = %s" % (sk['name'], sk['weight']), file=options)

        return options.getvalue()

    def queueskillrules_conf(self):
        """Generate queueskillrules.conf asterisk configuration file
        """
        options = StringIO()

        if self._mds:
            print('\n;Queue Skill Rules void for MDS', file=options)
        else:
            for r in asterisk_conf_dao.find_queue_skillrule_settings():
                print("\n[%s]" % r['name'], file=options)

                if 'rule' in r and r['rule'] is not None:
                    for rule in r['rule'].split(';'):
                        print("rule = %s" % rule, file=options)

        return options.getvalue()

    def queuerules_conf(self):
        options = StringIO()

        rule = None
        for m in asterisk_conf_dao.find_queue_penalties_settings():
            if m['name'] != rule:
                rule = m['name']
                print("\n[%s]" % rule, file=options)

            print("penaltychange => %d," % m['seconds'], end=' ', file=options)
            if m['maxp_sign'] is not None and m['maxp_value'] is not None:
                sign = '' if m['maxp_sign'] == '=' else m['maxp_sign']
                print("%s%d" % (sign, m['maxp_value']), end=' ', file=options)

            if m['minp_sign'] is not None and m['minp_value'] is not None:
                sign = '' if m['minp_sign'] == '=' else m['minp_sign']
                print(",%s%d" % (sign, m['minp_value']), end=' ', file=options)

            print(file=options)

        return options.getvalue()

    def rtp_conf(self):
        config_generator = RtpConf(asterisk_conf_dao, stun_enable=self._stun_enable, turn_enable=self._turn_enable)
        return self._generate_conf_from_generator(config_generator)
