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

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

import json
import unittest

from mock import Mock, sentinel
from xivo_sysconf.amqp_consumer import AMQPInterface, _ReloadIpbxEvent, _MessageHandler, Worker
from xivo_sysconf.service.proxy import ServiceProxy


class TestAMQPInterface(unittest.TestCase):

    def setUp(self):
        self.connection = Mock()
        self.service_proxy = Mock()
        self.bus_exchange = Mock
        self.amqp_interface = AMQPInterface(self.connection, self.service_proxy, self.bus_exchange)

    def test_start_and_stop(self):
        worker = Mock()
        self.amqp_interface._worker = worker

        self.amqp_interface.start()
        self.amqp_interface.stop()

        worker.run.assert_called_once_with()
        self.assertTrue(worker.should_stop)


class TestWorker(unittest.TestCase):

    def setUp(self):
        self.connection = Mock()
        self.exchange = Mock()
        self.msg_handler = Mock(_MessageHandler)
        self.worker = Worker(self.connection, self.exchange, self.msg_handler)

    def test_on_message(self):
        message = Mock()

        self.worker._on_message(sentinel.body, message)

        message.ack.assert_called_once_with()
        self.msg_handler.handle_msg.assert_called_once_with(sentinel.body)


class TestMessageHandler(unittest.TestCase):

    def setUp(self):
        self.event_handler = Mock()
        self.event_handler.Event.name = 'foobar'
        self.msg_handler = _MessageHandler([self.event_handler])

    def test_routing_keys(self):
        routing_keys = self.msg_handler.routing_keys()

        self.assertEqual(routing_keys, [self.event_handler.Event.routing_key])

    def test_handle_msg(self):
        msg = {'name': self.event_handler.Event.name}

        self.msg_handler.handle_msg(msg)

        self.event_handler.handle_event.assert_called_once_with(msg)

    def test_handle_msg_invalid(self):
        decoded_msg = {'name': 'invalid message'}
        msg = json.dumps(decoded_msg)

        self.assertRaises(Exception, self.msg_handler.handle_msg, msg)
        self.assertFalse(self.event_handler.handle_event.called)


class TestEventHandler(unittest.TestCase):

    def setUp(self):
        self.service_proxy = Mock(ServiceProxy)
        self.cmds = ['module reload', 'dialplan reload']
        self.decoded_msg = {'data': {'commands': self.cmds}}

    def test_ipbx_reload(self):
        handler = _ReloadIpbxEvent(self.service_proxy)

        handler.handle_event(self.decoded_msg)

        self.service_proxy.on_ipbx_reload.assert_called_once_with(self.cmds)
