# -*- 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, see <http://www.gnu.org/licenses/>

import unittest

from hamcrest import (assert_that,
                      contains_inanyorder)
from mock import Mock, sentinel
from xivo_bus.resources.ipbx.event import ReloadIpbxEvent

from xivo_confd.helpers.bus_publisher import BusPublisher

CONFIG = {
    'bus': {
        'host': 'example.org',
        'port': 5672,
        'username': 'foo',
        'password': 'bar',
        'exchange_name': 'xivo',
        'exchange_type': 'x-delayed-message',
        'exchange_args': {'x-delayed-type': 'topic'},
        'reload_delay': 1000,
    },
    'uuid': '111-2222',
}


class TestBusContext(unittest.TestCase):

    def test_new_from_config(self):
        publisher = BusPublisher.from_config(CONFIG)

        self.assertEqual(publisher.url, 'amqp://foo:bar@example.org:5672//')
        self.assertEqual(publisher.exchange_name, 'xivo')
        self.assertEqual(publisher.exchange_type, 'x-delayed-message')
        self.assertEqual(publisher.exchange_args, {'x-delayed-type': 'topic'})
        self.assertEqual(publisher.reload_delay, 1000)
        self.assertEqual(publisher.uuid, '111-2222')

    def test_send_messages_with_any_message(self):
        publish_func = Mock()
        publisher = BusPublisher.from_config(CONFIG)
        marshaler = Mock(content_type=sentinel.content_type)
        marshaler.marshal_message.return_value = sentinel.event
        routing_key = sentinel.routing_key
        expected_headers = None

        publisher.send_bus_event(sentinel.unmarshaled_event, routing_key)
        publisher.send_messages(marshaler, publish_func)

        publish_func.assert_called_once_with(sentinel.event,
                                             routing_key=routing_key,
                                             headers=expected_headers,
                                             content_type=sentinel.content_type)

    def test_send_messages_with_reload_message(self):
        publish_func = Mock()
        publisher = BusPublisher.from_config(CONFIG)
        marshaler = Mock(content_type=sentinel.content_type)
        marshaler.marshal_message.return_value = sentinel.event
        routing_key = 'config.ipbx.reload'
        expected_headers = {'x-delay': 1000}
        commands_list = ['dialplan reload', 'sip reload']
        reload_message = ReloadIpbxEvent(commands_list)

        publisher.send_bus_event(reload_message, routing_key)
        publisher.send_messages(marshaler, publish_func)

        publish_func.assert_called_once_with(sentinel.event,
                                             routing_key=routing_key,
                                             headers=expected_headers,
                                             content_type=sentinel.content_type)

    def test_add_optimized_reload_message(self):
        publisher = BusPublisher.from_config(CONFIG)
        commands_1 = ['dialplan reload', 'sip reload']
        commands_2 = ['dialplan reload', 'module reload app_queue.so']
        reload_message_1 = ReloadIpbxEvent(commands_1)
        reload_message_2 = ReloadIpbxEvent(commands_2)
        expected_commands = set(commands_1 + commands_2)

        publisher.add_optimized_reload_message(reload_message_1)
        publisher.add_optimized_reload_message(reload_message_2)

        assert_that(publisher.reload_message.commands, contains_inanyorder(*expected_commands))

    def test_delay_message(self):
        publisher = BusPublisher.from_config(CONFIG)
        routing_key = 'config.ipbx.reload'
        expected_headers = {'x-delay': 1000}

        headers = publisher.delay_message(routing_key)

        self.assertEqual(headers, expected_headers)
