# coding=utf-8
""""""
from __future__ import absolute_import, division, print_function, \
    unicode_literals

from datetime import datetime

from sqlalchemy.schema import Column
from sqlalchemy.types import DateTime, Integer
from whoosh.fields import ID

from ..extensions import db
from ..util import fqcn

#: Base Model class.
Model = db.Model


class Info(dict):
    def __init__(self, **kw):
        for k, v in kw.items():
            self[k] = v

    def copy(self):
        # dict.copy would return an instance of dict
        return self.__class__(**self)

    def __add__(self, other):
        d = self.copy()
        d.update(other)
        return d

    __or__ = __add__


EDITABLE = Info(editable=True)
NOT_EDITABLE = Info(editable=False)
AUDITABLE = Info(auditable=True)
AUDITABLE_HIDDEN = Info(auditable=True, audit_hide_content=True)
NOT_AUDITABLE = Info(auditable=False)
SEARCHABLE = Info(searchable=True)
NOT_SEARCHABLE = Info(searchable=False)
EXPORTABLE = Info(exportable=True)
NOT_EXPORTABLE = Info(exportable=False)

#: SYSTEM properties are properties defined by the system
#: and not supposed to be changed manually.
SYSTEM = Info(editable=False, auditable=False)


class IdMixin(object):
    id = Column(Integer, primary_key=True, info=SYSTEM | SEARCHABLE)


class Indexable(object):
    """Mixin with sensible defaults for indexable objects."""

    __indexable__ = True
    __indexation_args__ = {
        "index_to": (
            ("object_key", (("object_key", ID(stored=True, unique=True)),)),
            ("object_type", (("object_type", ID(stored=True, unique=False)),)),
        )
    }

    @classmethod
    def _object_type(cls):
        return fqcn(cls)

    @property
    def object_type(self):
        return self._object_type()

    @property
    def object_key(self):
        return "{}:{}".format(self.object_type, self.id)


class TimestampedMixin(object):
    #: creation date
    created_at = Column(DateTime, default=datetime.utcnow, info=SYSTEM | SEARCHABLE)
    #: last modification date
    updated_at = Column(
        DateTime,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
        info=SYSTEM | SEARCHABLE,
    )
    deleted_at = Column(DateTime, default=None, info=SYSTEM)
