# coding: utf-8
"""
Test functional suggestions backend.
"""

from __future__ import absolute_import, unicode_literals

import unittest

from django.core.management import call_command
from django.urls import reverse

import pytest

from rest_framework import status

import factories

from .base import BaseRestFrameworkTestCase
from .data_mixins import AddressesMixin

__title__ = "django_elasticsearch_dsl_drf_alt.tests.test_suggesters"
__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
__copyright__ = "2017-2020 Artur Barseghyan"
__license__ = "GPL 2.0/LGPL 2.1"
__all__ = ("TestFunctionalSuggesters",)


@pytest.mark.django_db
class TestFunctionalSuggesters(BaseRestFrameworkTestCase, AddressesMixin):
    """Test functional suggesters."""

    pytestmark = pytest.mark.django_db

    @classmethod
    def setUpClass(cls):
        """Set up class."""
        super(TestFunctionalSuggesters, cls).setUpClass()
        cls.publishers = []
        cls.publishers.append(
            factories.PublisherFactory(
                name="Addison–Wesley",
                city="Brighton & Hove",
                state_province="East Midlands",
                country="Armenia",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Adis International",
                city="Bristol",
                state_province="East of England",
                country="Argentina",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Atlantic Books",
                city="Cardiff",
                state_province="North East",
                country="Belgium",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Atlas Press",
                city="Carlisle",
                state_province="North West",
                country="Belarus",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Book League of America",
                city="Chelmsford",
                state_province="South East",
                country="Burkina Faso",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Strip Books of America",
                city="Chelmsford",
                state_province="South East",
                country="Burkina Faso",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Book Works",
                city="Chester",
                state_province="South West",
                country="Burundi",
            )
        )
        cls.publishers.append(
            factories.PublisherFactory(
                name="Booktrope",
                city="Chichester",
                state_province="West Midlands",
                country="Netherlands",
            )
        )

        cls.publishers_url = reverse("publisherdocument-functional-suggest", kwargs={})

        cls.books = []
        cls.books.append(
            factories.BookFactory(
                title="Aaaaa Bbbb",
                summary="`Twas brillig, and the slithy toves "
                "Did gyre and gimble in the wabe. "
                "All mimsy were the borogoves "
                "And the mome raths outgrabe.",
                publisher__name="Antares",
                publisher__country="Armenia",
            )
        )
        cls.books.append(
            factories.BookFactory(
                title="Aaaaa Cccc",
                summary='"Beware the Jabberwock, my son! '
                "The jaws that bite, the claws that catch! "
                "Beware the Jubjub bird, and shun "
                "The frumious Bandersnatch!",
                publisher__name="Antares",
                publisher__country="Armenia",
            )
        )
        cls.books.append(
            factories.BookFactory(
                title="Aaaaa Dddd",
                summary="He took his vorpal sword in his hand,"
                "Long time the manxome foe he sought --"
                "So rested he by the Tumtum tree,"
                "And stood awhile in thought.",
                publisher__name="Antares",
                publisher__country="Armenia",
            )
        )
        cls.books.append(
            factories.BookFactory(
                title="Eeeee Ffff",
                summary="He took his vorpal sword in his hand,"
                "Long time the manxome foe he sought --"
                "So rested he by the Tumtum tree,"
                "And stood awhile in thought.",
                publisher__name="Strip Books of America",
                publisher__country="Burkina Faso",
            )
        )

        cls.books += factories.BookFactory.create_batch(
            10,
            publisher__name="Oxford University Press",
            publisher__city="Yerevan",
            publisher__state_province="Ararat",
            publisher__country="Ireland",
        )

        cls.books_url = reverse(
            "bookdocument_functional_suggester-functional-suggest", kwargs={}
        )

        cls.authors = []
        cls.authors.append(
            factories.AuthorFactory(
                name="John Doe",
                salutation="Aaa Bbb",
            )
        )
        cls.authors.append(
            factories.AuthorFactory(
                name="Jane Doe",
                salutation="Aaa Ccc",
            )
        )
        cls.authors.append(
            factories.AuthorFactory(
                name="Armen Doe",
                salutation="Bbb Ccc",
            )
        )

        cls.authors_url = reverse("authordocument-functional-suggest", kwargs={})

        cls.created_addresses()

        cls.sleep()
        call_command("search_index", "--rebuild", "-f")

    def _test_suggesters(self, test_data, url):
        """Test suggesters."""
        self.authenticate()

        data = {}

        for _suggester_field, _test_cases in test_data.items():

            for _test_case, _expected_results in _test_cases.items():
                # Check if response now is valid
                response = self.client.get(
                    url + "?" + _suggester_field + "=" + _test_case, data
                )
                self.assertEqual(response.status_code, status.HTTP_200_OK)
                self.assertIn(_suggester_field, response.data)
                _unique_options = list(
                    set(
                        [
                            __o["text"]
                            for __o in response.data[_suggester_field][0]["options"]
                        ]
                    )
                )
                self.assertEqual(
                    len(_unique_options),
                    len(_expected_results),
                    (_test_case, _expected_results),
                )
                self.assertEqual(
                    sorted(_unique_options),
                    sorted(_expected_results),
                    (_test_case, _expected_results),
                )

    def test_suggesters_completion(self):
        """Test suggesters completion."""
        # Testing publishers
        test_data = {
            "name_suggest__completion_prefix": {
                "Ad": ["Addison–Wesley", "Adis International"],
                "Atl": ["Atlantic Books", "Atlas Press"],
                "Boo": ["Book League of America", "Book Works", "Booktrope"],
                "Stri": ["Strip Books of America"],
            },
            "name_match_suggest__completion_match": {
                "Strip": [
                    "Strip Books of America",
                ],
                "America": [
                    "Strip Books of America",
                    "Book League of America",
                ],
            },
            "country_suggest__completion_prefix": {
                "Arm": ["Armenia"],
                "Ar": ["Armenia", "Argentina"],
                "Bel": ["Belgium", "Belarus"],
                "Bur": ["Burkina Faso", "Burundi"],
                "Net": ["Netherlands"],
                "Fra": [],
            },
        }
        # Testing default suggesters as well
        test_data.update(
            {
                "name_suggest": test_data["name_suggest__completion_prefix"],
                "name_match_suggest": test_data["name_match_suggest__completion_match"],
                "country_suggest": test_data["country_suggest__completion_prefix"],
            }
        )
        self._test_suggesters(test_data, self.publishers_url)

        # Testing books
        test_data = {
            "title_suggest_prefix__completion_prefix": {
                "Aaa": ["Aaaaa Bbbb", "Aaaaa Cccc", "Aaaaa Dddd"],
                "Bbb": [],
            },
        }
        # Testing default suggesters as well
        test_data.update(
            {
                "title_suggest_prefix": test_data[
                    "title_suggest_prefix__completion_prefix"
                ],
                "title.raw__completion_prefix": test_data[
                    "title_suggest_prefix__completion_prefix"
                ],
                "title_simple__completion_prefix": test_data[
                    "title_suggest_prefix__completion_prefix"
                ],
            }
        )
        self._test_suggesters(test_data, self.books_url)

        # Testing authors
        test_data = {
            "salutation_suggest__completion_prefix": {
                "Aaa": ["Aaa Bbb", "Aaa Ccc"],
                "Bbb": ["Bbb Ccc"],
                "Hhh": [],
            },
        }
        # Testing default suggesters as well
        test_data.update(
            {
                "salutation_suggest": test_data[
                    "salutation_suggest__completion_prefix"
                ],
                "salutation.raw": test_data["salutation_suggest__completion_prefix"],
            }
        )
        self._test_suggesters(test_data, self.authors_url)

    def test_suggesters_completion_no_args_provided(self):
        """Test suggesters completion with no args provided."""
        data = {}
        # Check if response now is valid
        response = self.client.get(self.publishers_url, data)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

    # def test_suggesters_term(self):
    #     """Test suggesters term."""
    #     # Testing books
    #     test_data = {
    #         'summary_suggest__term': {
    #             'borogovse': ['borogov'],
    #             'Tumtus': ['tumtum'],
    #             'Jabberwok': ['jabberwock'],
    #             'tovse': ['tove', 'took', 'twas'],
    #         },
    #     }
    #     self._test_suggesters(test_data, self.books_url)
    #
    # def test_suggesters_phrase(self):
    #     """Test suggesters phrase."""
    #     # Testing books
    #     test_data = {
    #         'summary_suggest__phrase': {
    #             'slith tovs': ['slithi tov'],
    #             'mimsy boroto': ['mimsi borogov'],
    #         },
    #     }
    #     self._test_suggesters(test_data, self.books_url)
    #
    # def test_nested_fields_suggesters_completion(self):
    #     """Test suggesters completion for nested fields."""
    #     # Testing cities and countries
    #     test_data = {
    #         'city_suggest__completion': {
    #             'Ye': ['Yerevan', 'Yeovil'],
    #             'Yer': ['Yerevan'],
    #             'Ams': ['Amsterdam'],
    #             'Du': ['Dublin'],
    #             'Ne': [],
    #         },
    #         'country_suggest__completion': {
    #             'Arm': ['Armenia'],
    #             'Ar': ['Armenia', 'Argentina'],
    #             'Re': ['Republic of Ireland'],
    #             'Net': ['Netherlands'],
    #             'Fra': [],
    #         }
    #     }
    #     self._test_suggesters(test_data, self.addresses_suggest_url)


if __name__ == "__main__":
    unittest.main()
