# -*- 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 logging
from unittest import TestCase
from uuid import uuid4

from hamcrest import assert_that
from hamcrest import has_item
from hamcrest import has_property
from mock import Mock, ANY

from xivo_dird.dao import meetingroom
from ..xivo_meetingroom_backend import MeetingroomBackend

logger = logging.getLogger(__name__)

SOME_UUID = str(uuid4())

ROOM_1 = {
    'id': 1,
    'name': 'room 1',
    'display_name': 'display 1',
    'number': 'aaaa',
    'user-pin': '111',
    'uuid': '11111111-1111-1111-1111-111111111111',
    'room_type': 'static',
    'user_id': 11
}
ROOM_2 = {
    'id': 2,
    'name': 'room 2',
    'display_name': 'display 2',
    'number': 'bbbb',
    'user-pin': '2',
    'uuid': '22222222-2222-2222-2222-222222222222',
    'room_type': 'personal',
    'user_id': 22
}


class Result(dict):
    def _asdict(self):
        return self


class TestMeetingroomBackend(TestCase):

    def setUp(self):
        self._source = MeetingroomBackend()
        self._search_engine = Mock(meetingroom.MeetingroomSearchSystem)
        config = {
            'config': {
                'name': 'meetingroom',
                'get_all_rooms_keywords': 'conference',
                'searched_columns': 'display_name',
                'first_matched_columns': 'number'
            }
        }
        self._source.load(config, search_engine=self._search_engine)

    def test_search_name_static(self):
        self._search_engine.search.return_value = [[Result(ROOM_1)]]

        result = self._source.search('room', {'xivo_user_uuid': ROOM_1['user_id']})

        self._search_engine.search.assert_called_once_with(
            ANY, {'user_uuid': 11, 'searched_columns': 'display_name', 'search': 'room'})

        expected = ROOM_1.copy()
        expected.pop('room_type')
        assert_that(result, has_item(has_property('fields', expected)))
        assert_that(result, has_item(has_property('is_personal', False)))
        assert_that(result, has_item(has_property('is_deletable', False)))

    def test_search_name_personal(self):
        self._search_engine.search.return_value = [[Result(ROOM_2)]]

        result = self._source.search('room', {'xivo_user_uuid': ROOM_2['user_id']})

        self._search_engine.search.assert_called_once_with(
            ANY, {'search': 'room', 'searched_columns': 'display_name', 'user_uuid': 22})

        expected = ROOM_2.copy()
        expected.pop('room_type')
        assert_that(result, has_item(has_property('fields', expected)))
        assert_that(result, has_item(has_property('is_personal', True)))
        assert_that(result, has_item(has_property('is_deletable', False)))

    def test_first_match(self):
        self._search_engine.search.return_value = [[Result(ROOM_2)]]

        result = self._source.first_match('bbbb', {'xivo_user_uuid': ROOM_2['user_id']})

        self._search_engine.search.assert_called_once_with(
            ANY, {'number': 'bbbb', 'user_uuid': 22})

        expected = ROOM_2.copy()
        expected.pop('room_type')
        assert_that(result, has_property('fields', expected))
        assert_that(result, has_property('is_personal', True))
        assert_that(result, has_property('is_deletable', False))

    def test_list(self):
        self._search_engine.search.return_value = [[Result(ROOM_1)]]

        result = self._source.list([ROOM_1['uuid']], {'token_infos': {'xivo_user_uuid': 11}})

        self._search_engine.search.assert_called_once_with(
            ANY, {'unique_ids': ['11111111-1111-1111-1111-111111111111'], 'user_uuid': 11})

        expected = ROOM_1.copy()
        expected.pop('room_type')
        assert_that(result, has_item(has_property('fields', expected)))
        assert_that(result, has_item(has_property('is_personal', False)))
        assert_that(result, has_item(has_property('is_deletable', False)))

    def test_magic_keyword(self):
        self._search_engine.search.return_value = [[Result(ROOM_1)]]
        self._source.search('conference', {})
        self._search_engine.search.assert_called_once_with(
            ANY, {'search': '', 'searched_columns': 'display_name', 'user_uuid': None})
