"""
Test geo-spatial ordering filter backend.
"""

from __future__ import absolute_import

import unittest

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

import pytest

from rest_framework import status

import factories

from ..constants import (
    GEO_DISTANCE_ORDERING_PARAM,
    SEPARATOR_LOOKUP_COMPLEX_VALUE,
)
from .base import BaseRestFrameworkTestCase

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


@pytest.mark.django_db
class TestOrderingGeoSpatial(BaseRestFrameworkTestCase):
    """Test ordering geo-spatial."""

    pytestmark = pytest.mark.django_db

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

        cls.geo_origin = factories.PublisherFactory.create(
            **{
                "latitude": 48.8549,
                "longitude": 2.3000,
            }
        )

        cls.geo_in_count = 5
        cls.unit = "km"
        cls.algo = "plane"
        cls.geo_in = []
        for index in range(cls.geo_in_count):
            __publisher = factories.PublisherFactory.create(
                **{
                    "latitude": 48.8570 + index,
                    "longitude": 2.3005,
                }
            )
            cls.geo_in.append(__publisher)

        cls.base_publisher_url = reverse("publisherdocument-list", kwargs={})

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

    @pytest.mark.webtest
    def test_field_filter_geo_distance(self):
        """Field filter geo_distance.

        Example:

            http://localhost:8000
            /api/publisher/?ordering=location;48.85;2.30;km;plane
        """
        self.authenticate()

        __params = "location{sep}{lat}{sep}{lon}{sep}{unit}{sep}{algo}".format(
            lat=self.geo_origin.latitude,
            lon=self.geo_origin.longitude,
            unit=self.unit,
            algo=self.algo,
            sep=SEPARATOR_LOOKUP_COMPLEX_VALUE,
        )

        url = self.base_publisher_url[:] + "?{}={}".format(
            GEO_DISTANCE_ORDERING_PARAM, __params
        )

        data = {}
        response = self.client.get(url, data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # Should contain only 6 results
        self.assertEqual(len(response.data["results"]), self.geo_in_count + 1)
        item_count = len(response.data["results"])

        for counter, item in enumerate(response.data["results"]):
            if (counter > 1) and (counter < item_count + 1):
                self.assertLess(
                    response.data["results"][counter - 1]["location"]["lat"],
                    response.data["results"][counter]["location"]["lat"],
                )


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