# (c) cavaliba.com - IAM - models.py

# DEPRECATED IN V4.0

from django.db import models
from django.utils.translation import gettext_lazy as _

# # YAML export
# class MyYamlDumper(yaml.SafeDumper):
#     def write_line_break(self, data=None):
#         super().write_line_break(data)
#         if len(self.indents) < 2:
#             super().write_line_break()


# ---------------------------------------
# SireneUser
# ---------------------------------------


class SireneUser(models.Model):
    login = models.CharField(_("Login/Identifier(*)"), max_length=128, unique=True, blank=False)
    external_id = models.CharField(_("External ID"), max_length=128, null=True, blank=True)  # noqa: DJ001

    email = models.CharField(_("Email"), max_length=128, null=True, blank=True)  # noqa: DJ001
    mobile = models.CharField(_("Mobile"), max_length=32, null=True, blank=True)  # noqa: DJ001
    firstname = models.CharField(_("Firstname"), max_length=128, null=True, blank=True)  # noqa: DJ001
    lastname = models.CharField(_("Lastname"), max_length=128, null=True, blank=True)  # noqa: DJ001
    displayname = models.CharField(_("Display name"), max_length=500, null=True, blank=True)  # noqa: DJ001

    description = models.CharField(_("Description"), max_length=500, null=True, blank=True)  # noqa: DJ001
    is_enabled = models.BooleanField(_("Enabled"), default=True)
    last_login = models.DateTimeField(_("Last Login"), auto_now_add=False, blank=True, null=True)

    # Sirene Prefs
    want_notifications = models.BooleanField(_("Want Notifications"), default=True)
    want_24 = models.BooleanField(_("Want 24/24"), default=True)
    want_sms = models.BooleanField(_("Want SMS"), default=False)
    want_email = models.BooleanField(_("Want Email"), default=True)
    secondary_email = models.CharField(_("Secondary Email"), max_length=128, null=True, blank=True)  # noqa: DJ001
    secondary_mobile = models.CharField(  # noqa: DJ001
        _("Secondary Mobile"),
        max_length=128,
        null=True,
        blank=True,  # noqa: DJ001
    )

    last_update = models.DateTimeField(_("Last update"), auto_now_add=False, blank=True, null=True)

    class Meta:
        db_table = "iam_user"
        ordering = ["login"]
        verbose_name = "Sirene User"
        verbose_name_plural = "Sirene Users"
        # unique_together = ('login', 'site',)
        indexes = [
            models.Index(fields=["login"]),
            models.Index(fields=["is_enabled"]),
            models.Index(fields=["displayname"]),
            models.Index(fields=["email"]),
        ]

    def __str__(self):
        if self.displayname:
            return f"{self.login} - {self.displayname}"
        else:
            return f"{self.login}"

    # def to_dict(self):
    #     dict_attributs =  [
    #         "login", "firstname","lastname", "displayname", "email","mobile",
    #         "external_id", "is_enabled", "description",
    #         "want_notifications", "want_24", "want_email", "want_sms",
    #         "secondary_email", "secondary_mobile"
    #     ]
    #     m = {}
    #     m["classname"] = "user"
    #     m.update( model_to_dict(self, fields=dict_attributs) )

    #     # remove null values
    #     m2= {}
    #     for k,v in m.items():
    #         if not isinstance(v,bool):
    #             if v:
    #                 m2[k] = v
    #         else:
    #             m2[k] = v

    #     return m2

    # def to_yaml(self):

    #     data = self.to_dict()
    #     return yaml.dump([data], allow_unicode=True, Dumper=MyYamlDumper, sort_keys=False)


# ---------------------------------------
# SireneGroup & Role
# ---------------------------------------


class SireneGroup(models.Model):
    keyname = models.SlugField(
        _("Keyname(*)"),
        max_length=128,
        blank=False,
        unique=True,
    )
    displayname = models.CharField(_("Display name"), max_length=500, null=True, blank=True)  # noqa: DJ001
    description = models.CharField(_("Description"), max_length=500, null=True, blank=True)  # noqa: DJ001
    is_enabled = models.BooleanField(_("Enabled"), default=True)
    is_role = models.BooleanField(_("Role"), default=False)
    is_builtin = models.BooleanField(_("Built-in group"), default=False)
    users = models.ManyToManyField(SireneUser, blank=True)
    subgroups = models.ManyToManyField("self", symmetrical=False, blank=True)
    permissions = models.ManyToManyField("SirenePermission", blank=True)

    # 3.22 : grammar field for dynamic (compouted groups)
    autogroup = models.TextField(_("Autogroup"), null=True, blank=True)  # noqa: DJ001
    # cached computed users
    autogroup_users = models.ManyToManyField(SireneUser, related_name="+", blank=True)

    last_update = models.DateTimeField(_("Last update"), auto_now_add=False, blank=True, null=True)

    class Meta:
        db_table = "iam_group"
        ordering = ["keyname"]
        verbose_name = "Sirene Group"
        verbose_name_plural = "Sirene Groups"
        indexes = [
            models.Index(fields=["keyname"]),
            models.Index(fields=["is_enabled"]),
            models.Index(fields=["is_role"]),
        ]

    def __str__(self):
        return f"{self.keyname}"


#  -------------------------
# RBAC
# -------------------------
# SireneUser => SireneGroup (0..N)  =>  || => SireneRole (0..N) <= SirenePermission
# Roles are provided by each app (or global if app is Null)
# Roles are set of granular Permissions
# granular / atomic permission provided by each app
# p_xxx_permision[_c|_r|_u|_d|...]
# ex. p_home_access


class SirenePermission(models.Model):
    keyname = models.SlugField(_("Permission(*)"), max_length=128, blank=False, unique=True)
    displayname = models.CharField(_("Display name"), max_length=500, null=True, blank=True)  # noqa: DJ001
    description = models.CharField("Description", max_length=500, null=True, blank=True)  # noqa: DJ001
    is_builtin = models.BooleanField(_("Built-in permission"), default=False)

    class Meta:
        db_table = "iam_permission"
        ordering = ["keyname"]
        verbose_name = "Sirene Permission"
        verbose_name_plural = "Sirene Permissions"
        indexes = [
            models.Index(fields=["keyname"]),
            # models.Index(fields=["appname"]),
        ]

    def __str__(self):
        return f"{self.keyname}"


# -----------------------------------------------------------------------------
# Sirene Visitor
# ------------------------------------------------------------------------------
class SireneVisitor(models.Model):
    username = models.CharField(_("Username"), max_length=255, unique=True, blank=False)
    user_ip = models.CharField(_("Visitor IP"), max_length=64, default="")
    last_login = models.DateTimeField("Last Login", auto_now_add=False, blank=True, null=True)

    class Meta:
        db_table = "iam_visitor"
        ordering = ["last_login"]
        verbose_name = "Sirene Visitor"
        verbose_name_plural = "Sirene Visitors"
        indexes = [
            models.Index(fields=["username"]),
        ]

    def __str__(self):
        return self.username
