# (c) cavaliba.com - test / factory reset / operator account restore

import tempfile

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 DataInstance
from app_data.role import Role
from app_home.factory import factory_reset, restore_operator


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

    def _reset(self, username):
        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": username}, with_demo=False)

    def _role_admin_users(self):
        role = Role.from_keyname(keyname="role_admin")
        return role.fields["users"].value

    def test_operator_recreated_with_role_admin(self):
        report = self._reset("oauthadmin")

        self.assertEqual(report["errors"], [])
        self.assertTrue(report["operator"]["restored"])
        self.assertEqual(report["operator"]["username"], "oauthadmin")
        self.assertTrue(
            DataInstance.objects.filter(classname="user", keyname="oauthadmin").exists()
        )
        self.assertIn("oauthadmin", self._role_admin_users())

    def test_builtin_admin_is_still_in_role_admin(self):
        # the operator is appended, not substituted: the builtin admin account
        # must remain an admin or a wrong password locks the instance for good
        self._reset("oauthadmin")

        users = self._role_admin_users()
        self.assertIn("admin", users)
        self.assertIn("oauthadmin", users)

    def test_builtin_admin_operator_is_skipped(self):
        report = self._reset("admin")

        self.assertFalse(report["operator"]["restored"])
        self.assertEqual(report["operator"]["errors"], [])
        # the bootstrap re-provisions it anyway
        self.assertTrue(DataInstance.objects.filter(classname="user", keyname="admin").exists())
        self.assertIn("admin", self._role_admin_users())

    def test_internal_usernames_are_skipped(self):
        for username in ("", "-", "unknown", "cron", "CLI:load", "unittest:helper"):
            report = restore_operator(username)
            self.assertFalse(report["restored"], username)
            self.assertEqual(report["errors"], [], username)

    def test_restored_user_is_enabled(self):
        self._reset("oauthadmin")

        instance = DataInstance.objects.get(classname="user", keyname="oauthadmin")
        self.assertTrue(instance.is_enabled)
