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

"""

from django.db.models import Q
from django.urls import reverse
from django.test.client import Client

from compensation.tests.compensation.test_views import CompensationViewTestCase
from ema.models import Ema
from intervention.models import Responsibility
from konova.models import Geometry, Deadline, DeadlineType
from konova.settings import DEFAULT_GROUP, ETS_GROUP
from user.models import UserActionLogEntry


class EmaViewTestCase(CompensationViewTestCase):
    """ Test cases for EMA.

    Since we inherit most tests functions from CompensationViewTestCase, we only need to add some EMA specific
    test functions

    """
    ema = None

    @classmethod
    def setUpTestData(cls) -> None:
        super().setUpTestData()

    def setUp(self) -> None:
        super().setUp()
        # Create dummy data and related objects, like states or actions
        self.create_dummy_data()
        state = self.create_dummy_states()
        action = self.create_dummy_action()
        self.ema.before_states.set([state])
        self.ema.after_states.set([state])
        self.ema.actions.set([action])

        # Prepare urls
        self.index_url = reverse("ema:index", args=())
        self.new_url = reverse("ema:new", args=())
        self.new_id_url = reverse("ema:new-id", args=())
        self.detail_url = reverse("ema:detail", args=(self.ema.id,))
        self.log_url = reverse("ema:log", args=(self.ema.id,))
        self.edit_url = reverse("ema:edit", args=(self.ema.id,))
        self.remove_url = reverse("ema:remove", args=(self.ema.id,))
        self.share_url = reverse("ema:share-token", args=(self.ema.id, self.ema.access_token,))
        self.share_create_url = reverse("ema:share-form", args=(self.ema.id,))
        self.record_url = reverse("ema:record", args=(self.ema.id,))
        self.report_url = reverse("ema:report", args=(self.ema.id,))
        self.new_doc_url = reverse("ema:new-doc", args=(self.ema.id,))

        self.state_new_url = reverse("ema:new-state", args=(self.ema.id,))
        self.state_edit_url = reverse("ema:state-edit", args=(self.ema.id, state.id))
        self.state_remove_url = reverse("ema:state-remove", args=(self.ema.id, state.id,))

        self.action_new_url = reverse("ema:new-action", args=(self.ema.id,))
        self.action_edit_url = reverse("ema:action-edit", args=(self.ema.id, action.id))
        self.action_remove_url = reverse("ema:action-remove", args=(self.ema.id, action.id,))

        self.deadline = Deadline.objects.get_or_create(
            type=DeadlineType.FINISHED,
            date="2020-01-01",
            comment="TESTCOMMENT",
        )[0]
        self.ema.deadlines.add(self.deadline)

        self.deadline_new_url = reverse("ema:new-deadline", args=(self.ema.id,))
        self.deadline_edit_url = reverse("ema:deadline-edit", args=(self.ema.id, self.deadline.id))
        self.deadline_remove_url = reverse("ema:deadline-remove", args=(self.ema.id, self.deadline.id))

    def create_dummy_data(self):
        # Create dummy data
        # Create log entry
        action = UserActionLogEntry.get_created_action(self.superuser)
        # Create responsible data object
        responsibility_data = Responsibility.objects.create(
            handler=self.handler
        )
        geometry = Geometry.objects.create()
        self.ema = Ema.objects.create(
            identifier="TEST",
            title="Test_title",
            created=action,
            geometry=geometry,
            responsible=responsibility_data,
            comment="Test",
        )

    def test_logged_in_default_group_shared(self):
        """ Check correct status code for all requests

        OVERWRITES DEFAULT COMPENSATION TEST METHOD DUE TO SPECIFIC BEHAVIOUR OF EMAS

        Assumption: User logged in, is default group member and data is shared

        Normally default group would give access to all base functionalities. In case of EMAs we expect these
        requests to fail, since a user must be part of the ets group as well, not only default.

        Returns:

        """
        client = Client()
        client.login(username=self.superuser.username, password=self.superuser_pw)
        group = self.groups.get(name=DEFAULT_GROUP)
        self.superuser.groups.set([group])

        # Sharing does not have any effect in here, since the default group will prohibit further functionality access
        # to this user
        self.ema.share_with_user_list([self.superuser])

        success_urls = [
            self.index_url,
            self.detail_url,
            self.report_url,
            self.log_url,
        ]
        fail_urls = [
            self.new_url,
            self.new_id_url,
            self.edit_url,
            self.state_new_url,
            self.state_remove_url,
            self.state_edit_url,
            self.deadline_new_url,
            self.deadline_edit_url,
            self.deadline_remove_url,
            self.action_edit_url,
            self.action_remove_url,
            self.action_new_url,
            self.new_doc_url,
            self.remove_url,
        ]
        self.assert_url_fail(client, fail_urls)
        self.assert_url_success(client, success_urls)

    def test_logged_in_default_group_unshared(self):
        """ Check correct status code for all requests

        OVERWRITES DEFAULT COMPENSATION TEST METHOD DUE TO SPECIFIC BEHAVIOUR OF EMAS

        Assumption: User logged in, is default group member and data is NOT shared

        Normally default group would give access to all base functionalities. In case of EMAs we expect these
        requests to fail, since a user must be part of the ets group as well, not only default.

        We check on the same tests as in the _shared test, since we want to make sure there is no difference in
        between shared and unshared, if the user is only part of the default group.

        Returns:

        """
        client = Client()
        client.login(username=self.superuser.username, password=self.superuser_pw)
        group = self.groups.get(name=DEFAULT_GROUP)
        self.superuser.groups.set([group])

        # Sharing does not have any effect in here, since the default group will prohibit further functionality access
        # to this user
        self.ema.share_with_user_list([])

        success_urls = [
            self.index_url,
            self.detail_url,
            self.report_url,
        ]
        fail_urls = [
            self.new_url,
            self.new_id_url,
            self.edit_url,
            self.state_new_url,
            self.state_edit_url,
            self.state_remove_url,
            self.action_new_url,
            self.action_edit_url,
            self.action_remove_url,
            self.deadline_new_url,
            self.deadline_edit_url,
            self.deadline_remove_url,
            self.new_doc_url,
            self.log_url,
            self.remove_url,
        ]
        self.assert_url_fail(client, fail_urls)
        self.assert_url_success(client, success_urls)

    def test_logged_in_ets_group_shared(self):
        """ Check correct status code for all requests

        Assumption: User logged in, is conservation office group member and data is shared

        For EMAs we expect a user to be ETS and default group member to have full access to all functionalities, normally
        provided for default group members.

        Returns:

        """
        client = Client()
        client.login(username=self.superuser.username, password=self.superuser_pw)
        groups = self.groups.filter(Q(name=ETS_GROUP)|Q(name=DEFAULT_GROUP))
        self.superuser.groups.set(groups)
        # Sharing is inherited by base intervention for compensation. Therefore configure the interventions share state
        self.ema.share_with_user_list([self.superuser])

        success_urls = [
            self.index_url,
            self.detail_url,
            self.report_url,
            self.new_url,
            self.new_id_url,
            self.edit_url,
            self.state_new_url,
            self.state_edit_url,
            self.state_remove_url,
            self.deadline_new_url,
            self.deadline_edit_url,
            self.deadline_remove_url,
            self.action_new_url,
            self.action_edit_url,
            self.action_remove_url,
            self.new_doc_url,
            self.log_url,
            self.remove_url,
        ]
        self.assert_url_success(client, success_urls)

    def test_logged_in_ets_group_unshared(self):
        """ Check correct status code for all requests

        Assumption: User logged in, is conservation office group member and data is NOT shared

        For EMAs we expect a user to be ETS and default group member to have full access to all functionalities, normally
        provided for default group members.

        Returns:

        """
        client = Client()
        client.login(username=self.superuser.username, password=self.superuser_pw)
        groups = self.groups.filter(Q(name=ETS_GROUP)|Q(name=DEFAULT_GROUP))
        self.superuser.groups.set(groups)
        # Sharing is inherited by base intervention for compensation. Therefore configure the interventions share state
        self.ema.share_with_user_list([])

        success_urls = [
            self.index_url,
            self.detail_url,
            self.report_url,
            self.new_url,
            self.new_id_url,
        ]
        fail_urls = [
            self.edit_url,
            self.state_new_url,
            self.state_edit_url,
            self.state_remove_url,
            self.deadline_new_url,
            self.deadline_edit_url,
            self.deadline_remove_url,
            self.action_new_url,
            self.action_edit_url,
            self.action_remove_url,
            self.new_doc_url,
            self.log_url,
            self.remove_url,
        ]
        self.assert_url_success(client, success_urls)
        self.assert_url_fail(client, fail_urls)
