# coding: utf-8
"""
Test more-like-this functionality.
"""

from __future__ import absolute_import, unicode_literals

import unittest
import logging

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

__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__ = ("TestMoreLikeThis",)

LOGGER = logging.getLogger(__name__)


@pytest.mark.django_db
class TestMoreLikeThis(BaseRestFrameworkTestCase):
    """Test suggesters."""

    pytestmark = pytest.mark.django_db

    @classmethod
    def setUpClass(cls):
        """Set up class."""
        super(TestMoreLikeThis, cls).setUpClass()

        cls.lorem_books = factories.BookFactory.create_batch(200)

        cls.books = []

        cls.alice_books = []
        for book_data in factories.constants.NON_FAKER_BOOK_CONTENT:
            cls.alice_books.append(
                factories.BookChapterFactory(
                    title=book_data["title"],
                    summary=book_data["summary"],
                    description=book_data["description"],
                )
            )
        cls.alice_books_ids = [__obj.id for __obj in cls.alice_books]

        cls.sheckley_books = []
        for book_data in factories.constants.NON_FAKER_BOOK_CONTENT_OTHER:
            cls.sheckley_books.append(
                factories.BookNovelFactory(
                    title=book_data["title"],
                    summary=book_data["summary"],
                    description=book_data["description"],
                )
            )
        cls.sheckley_books_ids = [__obj.id for __obj in cls.sheckley_books]

        cls.books = []
        cls.books.extend(cls.alice_books)
        cls.books.extend(cls.sheckley_books)

        # Alice book
        cls.books_url_1 = reverse(
            "bookdocument_more_like_this-more-like-this", kwargs={"id": cls.books[0].id}
        )
        # Sheckley book
        cls.books_url_2 = reverse(
            "bookdocument_more_like_this-more-like-this",
            kwargs={"id": cls.books[-1].id},
        )

        # Alice book
        cls.books_url_1_no_options = reverse(
            "bookdocument_more_like_this_no_options-more-like-this",
            kwargs={"id": cls.books[0].id},
        )
        # Sheckley book
        cls.books_url_2_no_options = reverse(
            "bookdocument_more_like_this_no_options-more-like-this",
            kwargs={"id": cls.books[-1].id},
        )

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

    def _test_more_like_this(self, test_data_ids, url, strict=True):
        """Test more-like-this.

        We can't really predict which result would it show as most relevant,
        however we can for sure assume that no strange data shall appear
        in between.
        """
        self.authenticate()
        data = {}
        response = self.client.get(url, data)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        if strict:
            response_ids = [int(__r["id"]) for __r in response.data["results"]]

            self.assertFalse(bool(set(response_ids) - set(test_data_ids)))

    def test_more_like_this(self):
        """Test more-like-this."""
        # Testing publishers
        test_data_ids = []
        test_data_ids.extend(self.alice_books_ids)
        test_data_ids.extend(self.sheckley_books_ids)

        self._test_more_like_this(test_data_ids, self.books_url_1, strict=True)
        self._test_more_like_this(
            test_data_ids, self.books_url_1_no_options, strict=False
        )

        self._test_more_like_this(test_data_ids, self.books_url_2, strict=True)
        self._test_more_like_this(
            test_data_ids, self.books_url_2_no_options, strict=False
        )


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