# (c) cavaliba.com - test / factory reset / full run

import tempfile

from django.conf import settings
from django.core.cache import cache as cache_django
from django.test import TestCase, override_settings

import app_home.cache as cache
from app_data.models import DataClass, DataInstance, DataRevision
from app_data.registry import registry_get_key
from app_home.factory import factory_reset
from app_home.log import INFO, log
from app_home.models import CavalibaLog
from app_user.models import SirenePermission
from tests import helper


class TestFactoryResetRun(TestCase):
    def setUp(self):
        cache.clear()
        cache_django.clear()
        self.tmpdir = tempfile.mkdtemp()

    def _reset(self):
        with override_settings(
            CAVALIBA_FILESTORE=self.tmpdir,
            CAVALIBA_EXPORT_FOLDER=self.tmpdir,
            CAVALIBA_MAIL_FOLDER=self.tmpdir,
            CAVALIBA_SMS_FOLDER=self.tmpdir,
        ):
            return factory_reset(aaa={"username": "unittest"}, with_demo=False)

    def test_user_data_is_removed(self):
        helper.add_user(login="tobewiped")
        self.assertTrue(DataInstance.objects.filter(keyname="tobewiped").exists())

        report = self._reset()

        self.assertEqual(report["errors"], [])
        self.assertFalse(DataInstance.objects.filter(keyname="tobewiped").exists())

    def test_logs_and_revisions_are_removed(self):
        log(INFO, app="unittest", view="factory", action="seed", status="OK", data="seed")
        helper.add_user(login="revuser")
        self.assertTrue(CavalibaLog.objects.filter(app="unittest").exists())
        self.assertTrue(DataRevision.objects.exists())

        report = self._reset()

        self.assertFalse(CavalibaLog.objects.filter(app="unittest").exists())
        self.assertFalse(DataRevision.objects.filter(keyname="revuser").exists())
        self.assertGreater(report["deleted"]["log"], 0)

    def test_builtin_is_reprovisioned(self):
        self._reset()

        # schemas, permissions and the builtin admin user are back
        self.assertGreater(DataClass.objects.count(), 0)
        self.assertGreater(SirenePermission.objects.filter(is_builtin=True).count(), 0)
        self.assertTrue(
            DataInstance.objects.filter(classname="user", keyname="admin").exists(),
            "builtin admin user not reprovisioned",
        )

    def test_db_version_matches_code_version(self):
        report = self._reset()

        self.assertEqual(report["db_version"], settings.CAVALIBA_VERSION)
        self.assertEqual(registry_get_key(key="DB_VERSION"), settings.CAVALIBA_VERSION)
        self.assertTrue(registry_get_key(key="INSTANCE_UUID"))

    def test_django_internals_are_kept(self):
        from django.contrib.auth import get_user_model
        from django.contrib.contenttypes.models import ContentType

        UserModel = get_user_model()
        UserModel.objects.create_user(username="djangokept", password="x")
        contenttypes_before = ContentType.objects.count()

        self._reset()

        self.assertTrue(UserModel.objects.filter(username="djangokept").exists())
        self.assertEqual(ContentType.objects.count(), contenttypes_before)
