# -*- coding: utf-8 -*-
"""
Property model
"""

from django.db import models

from .. import utils
from .acl import AccessibleMixin


class Property(models.Model, AccessibleMixin):
    class Meta:
        verbose_name_plural = "properties"
        indexes = [
            models.Index(fields=["origin", "name"], name="property_origin_name_idx"),
        ]

    #: Name of the Property
    name = models.CharField(max_length=255, db_index=True)
    #: Value of the Property
    value = models.TextField(blank=True, null=True)
    #: Type of the Property
    type = models.CharField(max_length=255, choices=[(x, x) for x in ("string", "python", "dynamic")])
    #: The owner of this Property. Changes require `entrust` permission.
    owner = models.ForeignKey("Object", related_name="+", null=True, on_delete=models.SET_NULL)
    #: The object on which this Property is defined
    origin = models.ForeignKey("Object", related_name="properties", on_delete=models.CASCADE)
    #: If True, this Property’s owner will be reassigned on child instances
    inherit_owner = models.BooleanField(default=False)

    __original_inherit_owner = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__original_inherit_owner = self.inherit_owner

    @property
    def kind(self):
        return "property"

    def __str__(self):
        return "%s {#%s on %s}" % (self.name, self.id, self.origin)

    def save(self, *args, **kwargs):
        needs_default_permissions = self.pk is None
        if not needs_default_permissions:
            self.origin.can_caller("write", self)  # pylint: disable=no-member
        super().save(*args, **kwargs)
        if self.inherit_owner and not self.__original_inherit_owner:
            for child in self.origin.get_descendents():  # pylint: disable=no-member
                Property.objects.update_or_create(
                    name=self.name,
                    origin=child,
                    defaults=dict(
                        owner=child.owner,
                        inherit_owner=self.inherit_owner,
                    ),
                    create_defaults=dict(
                        owner=child.owner,
                        inherit_owner=self.inherit_owner,
                        value=self.value,
                        type=self.type,
                    ),
                )
        if not needs_default_permissions:
            return
        utils.apply_default_permissions(self)
