"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 15.12.21

"""
from django.contrib.gis.db.models.functions import Translate

from konova.models import Geometry, GeometryConflict
from konova.tests.test_views import BaseTestCase
from konova.utils.schneider.fetcher import ParcelFetcher


class GeometryTestCase(BaseTestCase):
    @classmethod
    def setUpTestData(cls):
        super().setUpTestData()
        geom = cls.create_dummy_geometry()
        cls.geom_1 = Geometry.objects.create(
            geom=geom,
        )
        cls.geom_2 = Geometry.objects.create(
            geom=geom,
        )

    def test_geometry_parcel_caluclation(self):
        """ Tests whether newly created geometries already have parcels calculated during save

        Returns:

        """
        has_parcels = self.geom_1.parcels.all().exists()
        self.assertFalse(has_parcels, msg=f"{self.geom_1.id} has parcels but should not!")
        self.geom_1.update_parcels()
        self.geom_1.refresh_from_db()
        parcels = self.geom_1.parcels.all()
        has_parcels = parcels.exists()
        parcel_districts = parcels.values_list("district", flat=True)
        self.assertTrue(has_parcels, msg=f"{self.geom_1.id} has no parcels but should!")
        self.assertEqual(parcels.count(), len(parcel_districts), msg=f"Not every parcel has exactly one district!")

    def test_geometry_conflict(self):
        """ Tests whether a geometry conflict will be present in case of identical/overlaying geometries and
        if the conflict will be resolved if one geometry is edited.

        Returns:

        """
        self.geom_2.check_for_conflicts()
        conflict = GeometryConflict.objects.all()
        self.assertEqual(1, conflict.count())
        conflict = conflict.first()
        self.assertEqual(conflict.conflicting_geometry, self.geom_2)
        self.assertEqual(conflict.affected_geometry, self.geom_1)

        # Move geom_2 somewhere else, expect the conflict to be resolved
        Geometry.objects.filter(id=self.geom_2.id).update(
            geom=Translate('geom', 100000, 100000)
        )
        self.geom_2.refresh_from_db()
        self.geom_1.check_for_conflicts()
        num_conflict = GeometryConflict.objects.all().count()
        self.assertEqual(0, num_conflict)

    def test_fetch(self):
        """ Tests the fetching functionality of ParcelFetcher

        +++ Test relies on the availability of the spatial computation component 'Schneider' +++

        Returns:

        """
        fetcher = ParcelFetcher(geometry=self.geom_1)
        features = fetcher.get_parcels()
        self.assertNotEqual(0, len(features), msg="Spatial fetcher get feature did not work!")