# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 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 hamcrest import assert_that, equal_to

from xivo_dao.alchemy.labels import Labels
from xivo_dao.helpers.exception import ResourceError
from xivo_dao.resources.labels import dao as label_dao, validator
from xivo_dao.resources.user import dao as user_dao
from xivo_dao.resources.utils.search import SearchResult
from xivo_dao.tests.test_dao import DAOTestCase


class TestLabelExist(DAOTestCase):

    def test_given_no_label_then_returns_false(self):
        result = label_dao.exists(1)

        assert_that(result, equal_to(False))

    def test_given_label_exists_then_return_true(self):
        label_row = self.add_label()

        result = label_dao.exists(label_row.id)

        assert_that(result, equal_to(True))


class TestLabelCRUD(DAOTestCase):

    def test_get_all_labels(self):
        self.add_user(callerid='"John Doe"')

        label_row = self.add_label()
        result = label_dao.search()

        expected = SearchResult(total=1, items=[label_row])

        assert_that(result[1][0].users_count, equal_to(0))
        assert_that(result, equal_to(expected))

    def test_create_label(self):
        props = {
            'display_name': 'MyLabel',
            'description': 'Any Label'
        }
        label = label_dao.create(Labels(**props))
        expected = label_dao.get(label.id)
        assert_that(label, equal_to(expected))

    def test_create_duplicate_label(self):
        props = {
            'display_name': 'MyLabel',
            'description': 'Any Label'
        }

        label = label_dao.create(Labels(**props))
        self.assertRaises(ResourceError, validator.validate_create, label.display_name)

    def test_get_all_labels_with_associated_user(self):
        label_row = self.add_label()
        user = self.add_user(callerid='"John Doe"')

        user.labels.append(label_row)
        result = label_dao.search()

        expected = SearchResult(total=1, items=[label_row])

        assert_that(result[1][0].users_count, equal_to(1))
        assert_that(result, equal_to(expected))

    def test_delete_label(self):
        label_row = self.add_label()

        label_dao.delete(label_row)

        expected = SearchResult(total=0, items=[])
        result = label_dao.search()

        assert_that(result, equal_to(expected))

    def test_delete_associated_label(self):
        label_row = self.add_label()
        user = self.add_user(callerid='"John Doe"')

        user.labels.append(label_row)

        label_dao.delete(label_row)

        expected_label = SearchResult(total=0, items=[])

        result_label = label_dao.search()
        result_user = user_dao.find_by_id_uuid(user.id)

        assert_that(result_label, equal_to(expected_label))
        assert_that(result_user.id, equal_to(user.id))
        assert_that(len(result_user.labels), equal_to(0))

    def test_edit_label(self):
        label = self.add_label()
        label.display_name = 'MyLabel'
        label.description = 'Any Label'

        label_dao.edit(label)
        result = label_dao.get(label.id)

        assert_that(result, equal_to(label))
