from peewee import CharField, Check, TextField

from defence360agent.feature_management.constants import (
    AV,
    AV_REPORT,
    FULL,
    LOG,
    NA,
    PROACTIVE,
)
from defence360agent.model import Model, instance


class FeatureManagementPerms(Model):
    """Permissions state for Feature Management.

    Each record/instance is a set of permissions of a single user.
    """

    DEFAULT = ""

    class Meta:
        database = instance.db
        db_table = "feature_management_permissions"

    #: The username of the end-user, or an empty string for the default value
    #: for all new users.
    user = CharField(unique=True)
    #: How much the user can access and control Proactive Defense feature.
    #: Must be one of :obj:`.NA`, :obj:`.LOG` or :obj:`.FULL`.
    proactive = TextField(
        null=False,
        constraints=[
            Check("proactive in ('{}','{}','{}')".format(NA, LOG, FULL))
        ],
        default=FULL,
    )
    #: How much the user can access and control Proactive Defense feature.
    #: Must be either :obj:`.NA` or :obj:`.AV_REPORT` or :obj:`.FULL`.
    av = TextField(
        null=False,
        constraints=[
            Check("av in ('{}','{}','{}')".format(NA, AV_REPORT, FULL))
        ],
        default=AV_REPORT,
    )

    @classmethod
    def get_perm(cls, user: str) -> "FeatureManagementPerms":
        """
        Get feature permissions by user name

        :param user: user name
        :return: :class:`FeatureManagementPerms` object for user
        """
        default = cls.get_default()

        if user is None:
            return default

        defaults = {
            AV: default.av,
            PROACTIVE: default.proactive,
        }

        perm, _ = cls.get_or_create(user=user, defaults=defaults)
        return perm

    @classmethod
    def get_default(cls):
        """Get default permissions"""
        return cls.get(user=cls.DEFAULT)

    def is_default(self):
        """Check if current permission is default"""
        return self.user == self.DEFAULT

    def get_feature(self, key: str) -> str:
        """Get permission by feature name"""
        return getattr(self, key)

    def set_feature(self, key: str, value: str):
        """Set permission"""
        setattr(self, key, value)
        self.save()

    def as_dict(self):
        return {
            AV: self.av,
            PROACTIVE: self.proactive,
        }
