# (c) cavaliba.com - tests / data / exporter progress modal footer per task state
#
# The footer used to depend on p_task_view too (no Hide without it, since the
# modal was then the user's only view of their export). That permission is gone
# and the Tasks menu needs none, so the footer is a function of task state only.

import shutil
import tempfile

from django.test import TestCase, override_settings
from django.urls import reverse

import app_home.cache as cache
from app_data.exporter import ExportSpec
from app_data.models import DataTask
from app_data.task_manager import create_datatask
from tests import helper

AAA = {"username": "unittest", "perms": ["p_data_admin"]}
BASE_PERMS = ["p_data_export", "p_data_access", "p_data_read"]


@override_settings(CAVALIBA_AUTH_MODE="unittest")
class ViewExporterModalButtonsTest(TestCase):
    def _isolate_filestore(self):
        """Point the filestore at a throwaway directory for this test."""

        rootdir = tempfile.mkdtemp(prefix="cavaliba_test_filestore_")
        override = override_settings(CAVALIBA_FILESTORE=rootdir)
        override.enable()
        self.addCleanup(override.disable)
        self.addCleanup(shutil.rmtree, rootdir, ignore_errors=True)
        return rootdir

    def setUp(self):
        self._isolate_filestore()
        cache.clear()
        helper.add_user_with_perm(login="unittest", perms=BASE_PERMS)
        helper.add_schema(
            classname="vbtn",
            field_definition={
                "mystring": {"dataformat": "string", "displayname": "MyString"},
            },
        )
        helper.add_instance(classname="vbtn", keyname="vbtn-01", fields={"mystring": "one"})

        self.params = {"spec": ExportSpec(schema="vbtn", format="csv").to_dict(), "aaa": AAA}
        self.task = create_datatask(
            name="Export csv - vbtn", params=self.params, owner_type="user", owner_id="unittest"
        )

    def _running(self):
        DataTask.objects.filter(handle=self.task.handle).update(state="RUNNING")

    def _done(self):
        DataTask.objects.filter(handle=self.task.handle).update(state="DONE")

    def _get(self):
        return self.client.get(reverse("app_data:data_exporter_progress", args=[self.task.handle]))

    # ---------------------------------------------------------------
    # running : abort + hide, for every owner (no task permission)
    # ---------------------------------------------------------------

    def test_running_offers_abort_and_hide(self):
        self._running()

        response = self._get()

        self.assertContains(response, "Abort")
        self.assertContains(response, "data-bs-dismiss")
        self.assertContains(response, "Hide")

    def test_running_does_not_say_close(self):
        self._running()

        response = self._get()

        self.assertNotContains(response, ">Close<")

    def test_queued_counts_as_running_for_the_footer(self):
        response = self._get()

        self.assertEqual(self.task.state, "QUEUED")
        self.assertContains(response, "Abort")
        self.assertContains(response, "Hide")

    # ---------------------------------------------------------------
    # terminal : close only, abort gone
    # ---------------------------------------------------------------

    def test_done_offers_close_not_hide(self):
        self._done()

        response = self._get()

        self.assertContains(response, "data-bs-dismiss")
        self.assertContains(response, "Close")
        self.assertNotContains(response, ">Hide<")
        self.assertNotContains(response, "Abort")

    def test_aborted_offers_close_only(self):
        DataTask.objects.filter(handle=self.task.handle).update(state="ABORTED")

        response = self._get()

        self.assertContains(response, "Close")
        self.assertNotContains(response, "Abort<")

    # ---------------------------------------------------------------
    # the modal itself must have no other exit, or the above is moot
    # ---------------------------------------------------------------

    def test_modal_shell_cannot_be_dismissed_another_way(self):
        from django.template.loader import get_template

        source = get_template("app_data/exporter.html").template.source

        self.assertIn('data-bs-backdrop="static"', source)
        self.assertIn('data-bs-keyboard="false"', source)
        self.assertNotIn("btn-close", source)
