from django.db import models


class SandboxContext(models.Model):
    """
    Sandbox context.
    Represented as model to add IPC possibility
    """

    class Keys(models.TextChoices):
        # Whether provision pack was generated.
        # Should be set to 'true' after generation
        IS_PROVISION_GENERATED = 'Provision is generated'

    key = models.CharField(max_length=200, null=False, primary_key=True)
    value = models.CharField(max_length=400, default='', null=False)

    @classmethod
    def is_provision_generated(cls):
        obj, _ = cls.objects.get_or_create(key=cls.Keys.IS_PROVISION_GENERATED)
        return bool(obj.value)

    @classmethod
    def set_provision_generated(cls, val: bool):
        obj, _ = cls.objects.get_or_create(key=cls.Keys.IS_PROVISION_GENERATED)
        if val:
            obj.value = 'yes'
        else:
            obj.value = ''
        obj.save()

    @classmethod
    def cleanup(cls):
        cls.set_provision_generated(False)


class SandboxActions(models.TextChoices):
    GENERATE_PROVISION = 'Provision package generation'
    CREATE_EMULATORS = 'Create emulators'
    PERFORM_PROVISION = 'Perform devices provision'
    REGISTER_DEVICES = 'Register devices at Virgil cloud'
    PUBLISH_NEW_TRUST_LIST = 'Generate and publish new TrustList'
    PUBLISH_NEW_DEVICE_EMULATOR_FW = 'Sign and publish new firmware for IoT-Device emulator'
    PUBLISH_NEW_GATEWAY_EMULATOR_FW = 'Sign and publish new firmware for Gateway emulator'
    RESET = 'Sandbox reset'


class ActionsRegistry(models.Model):
    """
    Sandbox actions registry.
    Represented as model to add IPC possibility
    """
    name = models.CharField(max_length=100, null=False, primary_key=True, choices=SandboxActions.choices)
    in_progress = models.BooleanField(default=False, null=False)

    @classmethod
    def add_in_progress(cls, action: SandboxActions):
        obj, _ = cls.objects.get_or_create(name=action)
        obj.in_progress = True
        obj.save()

    @classmethod
    def remove_in_progress(cls, action: SandboxActions):
        obj, _ = cls.objects.get_or_create(name=action)
        obj.in_progress = False
        obj.save()

    @classmethod
    def get_in_progress(cls):
        """
        :return: list of actions currently in progress
        """
        return [SandboxActions(a.name) for a in cls.objects.all() if a.in_progress]
