# -*- coding: utf-8 -*-
#
# Copyright (C) 2026 XiVO Solutions
#
# 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
from hamcrest import contains_exactly
from hamcrest import contains_inanyorder
from hamcrest import equal_to

from .base_dird_integration_test import BaseDirdIntegrationTest


def _firstnames(result):
    return [entry['column_values'][0] for entry in result['results']]


WS_TOKEN = 'valid-ws-token'


class TestLookupByLabels(BaseDirdIntegrationTest):
    asset = 'lookup_by_labels'

    def lookup_by_labels(self, term, labels, token=WS_TOKEN):
        # Use a web service token: lookup_by_label authorizes its labels via
        # per-label ACLs (granted by the mock), exercising the search service's
        # label -> sources behaviour without a user -> label database.
        return super().lookup_by_labels(term, labels, token=token)

    # config (etc/xivo-dird/config.yml):
    #   default_sources: [dir_default]               -> Default Smith
    #   label 1: [dir_a, dir_shared]                 -> Alice Smith, Shared Smith
    #   label 2: [dir_b, dir_shared]                 -> Bob Smith, Shared Smith
    #   display 'lookup_by_labels_display'           -> [Firstname, Lastname, Number]

    def test_that_no_labels_falls_back_to_default_sources(self):
        result = self.lookup_by_labels('smith', [])

        assert_that(_firstnames(result), contains_inanyorder('Default'))

    def test_that_a_mapped_label_queries_only_its_sources_not_defaults(self):
        result = self.lookup_by_labels('smith', [1])

        assert_that(_firstnames(result), contains_inanyorder('Alice', 'Shared'))

    def test_that_an_unmapped_label_falls_back_to_default_sources(self):
        result = self.lookup_by_labels('smith', [999])

        assert_that(_firstnames(result), contains_inanyorder('Default'))

    def test_that_multiple_labels_return_the_deduplicated_union(self):
        result = self.lookup_by_labels('smith', [1, 2])

        # dir_shared is mapped to both labels but must appear only once
        assert_that(_firstnames(result), contains_inanyorder('Alice', 'Bob', 'Shared'))

    def test_that_when_only_one_of_several_labels_is_mapped_no_defaults_are_added(self):
        result = self.lookup_by_labels('smith', [1, 999])

        assert_that(_firstnames(result), contains_inanyorder('Alice', 'Shared'))

    def test_that_the_configured_display_is_applied(self):
        result = self.lookup_by_labels('smith', [1])

        assert_that(result['column_headers'],
                    contains_exactly('Firstname', 'Lastname', 'Number'))
