# (c) cavaliba.com - data - field - boolean

"""
FieldBoolean: dataformat "boolean". Values are stored/returned as Python bool.

Method inventory: __init__, get_first_value, is_field_true, merge_request,
merge_import, get_snapshot_value, is_valid.
"""

from django.conf import settings

from .field import Field


# -------------
# BOOLEAN
# -------------
class FieldBoolean(Field):
    def __init__(self, fieldname, fieldschema, alljson):
        """Like Field.__init__, but unpacks a space-separated default_value string
        into a list of bools (only used when alljson has no value for this field)."""
        super().__init__(fieldname, fieldschema, alljson)

        # if no json, unpack default_value
        if not alljson:
            if self.default_value:
                ml = self.default_value.split()
                try:
                    self.value = [i in settings.TRUE_LIST for i in ml]
                except Exception:
                    self.value = []

    def get_first_value(self):
        """Return True if the single stored value is truthy (in settings.TRUE_LIST), else False."""
        try:
            return self.value[0] in settings.TRUE_LIST
        except Exception:
            return False

    def is_field_true(self):
        """Return True if there is exactly one value and it is truthy."""
        if len(self.value) == 1:
            if self.value[0] in settings.TRUE_LIST:
                return True
        return False

    def merge_request(self, request):
        """Set self.value to a list of bools from request.POST.getlist(fieldname)."""

        data = request.POST.getlist(self.fieldname, default=[])
        self.value = []
        if not data:
            return
        if type(data) is list:
            for i in data:
                try:
                    r = i in settings.TRUE_LIST
                    self.value.append(r)
                except Exception:
                    pass
        else:
            try:
                r = data in settings.TRUE_LIST
                self.value.append(r)
            except Exception:
                pass

    def merge_import(self, data):
        """Set self.value to a list of bools from an import/API payload (str/list of str)."""

        self.value = []
        if type(data) is list:
            for i in data:
                r = i in settings.TRUE_LIST
                self.value.append(r)
        else:
            r = data in settings.TRUE_LIST
            self.value.append(r)

    def get_snapshot_value(self):
        """Normalize [] and [False] to [False] so unchecked checkboxes don't produce spurious revision diffs."""
        return [False] if not self.value else list(self.value)

    def is_valid(self):
        """Cardinality check (super) plus: every stored value must be an actual bool."""
        r = super().is_valid()
        for b in self.value:
            if not isinstance(b, (bool)):
                return False
        return r
