# -*- coding: UTF-8 -*-

# Copyright (C) 2015-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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


import base64
import hashlib
import unittest

from hamcrest import assert_that, equal_to
from mock import Mock, patch
from xivo_dao.alchemy.infos import Infos
from xivo_dao.alchemy.mediaserver import MediaServer

from xivo_confgen.generators.sip_mds_trunk import SipMdsTrunkGenerator
from xivo_confgen.generators.tests.util import assert_section_equal


class TestSipMdsTrunkGenerator(unittest.TestCase):
    XIVO_UUID = "978ae445-2884-46c9-a9d7-b15d6b02b411"
    XIVO_INFO = Infos(uuid=XIVO_UUID)
    MDS_SECRET = base64.urlsafe_b64encode(hashlib.sha256(bytearray(XIVO_UUID, 'utf-8')).digest())

    def setUp(self):
        self.asterisk_conf_dao = Mock()
        self.asterisk_conf_dao.find_all_mediaservers.return_value = []
        self.generator = SipMdsTrunkGenerator(self.asterisk_conf_dao)

    @patch('xivo_dao.resources.infos.dao.get', Mock(return_value=XIVO_INFO))
    def generate_output(self):
        return '\n'.join(self.generator.generate())

    def test_given_no_sip_trunks_then_nothing_is_generated(self):
        output = self.generate_output()
        assert_that(output, equal_to(''))

    def test_given_one_mds_then_two_sections_are_generated(self):
        mds = MediaServer(id=1,
                          name="mds1",
                          display_name="Media Server 1",
                          voip_ip="10.49.0.1",
                          read_only="false")

        self.asterisk_conf_dao.find_all_mediaservers.return_value = [mds]

        output = self.generate_output()
        assert_section_equal(output, '''
            [from-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = user
            remotesecret = {secret}
            context = xds-from-mds
    
            [to-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = peer
            remotesecret = {secret}
            context = default
            port = 5060
            host = {voip_ip}
            fromuser = from-default
            username = from-default
            qualify = yes
        '''.format(secret=self.MDS_SECRET, voip_ip=mds.voip_ip))

    def test_generate_no_section_for_local_mds(self):
        mds0 = MediaServer(id=0,
                           name="default",
                           display_name="Default mediaserver",
                           voip_ip="10.49.0.99",
                           read_only="true")
        mds1 = MediaServer(id=1,
                           name="mds1",
                           display_name="Media Server 1",
                           voip_ip="10.49.0.1",
                           read_only="false")
        self.generator.systemname = "default"
        self.asterisk_conf_dao.find_all_mediaservers.return_value = [mds0, mds1]

        output = self.generate_output()
        assert_section_equal(output, '''
            [from-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = user
            remotesecret = {secret}
            context = xds-from-mds
    
            [to-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = peer
            remotesecret = {secret}
            context = default
            port = 5060
            host = {voip_ip}
            fromuser = from-default
            username = from-default
            qualify = yes
        '''.format(secret=self.MDS_SECRET, voip_ip=mds1.voip_ip))

    def test_given_two_mds_then_four_sections_are_generated(self):
        mds1 = MediaServer(id=1,
                           name="mds1",
                           display_name="Media Server 1",
                           voip_ip="10.49.0.1",
                           read_only="false")
        mds2 = MediaServer(id=2,
                           name="mds2",
                           display_name="Media Server 2",
                           voip_ip="10.49.0.2",
                           read_only="false")

        self.asterisk_conf_dao.find_all_mediaservers.return_value = [mds1, mds2]

        output = self.generate_output()
        assert_section_equal(output, '''
            [from-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = user
            remotesecret = {secret}
            context = xds-from-mds
    
            [to-mds1]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = peer
            remotesecret = {secret}
            context = default
            port = 5060
            host = {voip1_ip}
            fromuser = from-default
            username = from-default
            qualify = yes

            [from-mds2]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = user
            remotesecret = {secret}
            context = xds-from-mds
    
            [to-mds2]
            call-limit = 0
            subscribemwi = no
            amaflags = default
            transport = udp
            regseconds = 0
            secret = {secret}
            type = peer
            remotesecret = {secret}
            context = default
            port = 5060
            host = {voip2_ip}
            fromuser = from-default
            username = from-default
            qualify = yes
        '''.format(secret=self.MDS_SECRET, voip1_ip=mds1.voip_ip, voip2_ip=mds2.voip_ip))
