import logging

from django.forms import model_to_dict

from intranet.search.core.models import Facet


from .base import ArtefactStorage, BufferedStorageMixin


log = logging.getLogger(__name__)


class FacetStorage(BufferedStorageMixin, ArtefactStorage):
    MAX_LENGTH = 255
    key_prefix = 'facets:buffer'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.buffer_key = self.revision['id']

    def _create(self, facet):
        data = {
            'facet': facet['name'],
            'value': facet['value'],
            'label_ru': facet['label_ru'],
            'label_en': facet['label_en'],
        }

        id_ = '{}{}'.format(facet['name'], facet['value'])
        return id_, data

    def _flush(self, data):
        base = self.get_base_lookup()

        if isinstance(data['value'], str) and len(data['value']) > self.MAX_LENGTH:
            log.error('Facet value too long. Revision %s, full data: %s', base['revision_id'], data)
            return

        for field in ('label_ru', 'label_en'):
            data[field] = data.get(field, '')[:self.MAX_LENGTH]

        base.update({
            'facet': data['facet'],
            'value': data['value'],
        })

        defaults = {
            'label_ru': data['label_ru'],
            'label_en': data['label_en'],
        }

        facet, created = Facet.objects.get_or_create(defaults=defaults, **base)

        if not created:
            facet.label_en = data['label_en']
            facet.label_ru = data['label_ru']
            facet.save()

    def get(self, **kwargs):
        base = self.get_base_lookup()

        for lookup in ('facet', 'id__in', 'value__in', 'search', 'index'):
            if lookup in kwargs:
                base[lookup] = kwargs.pop(lookup)

        queryset = Facet.objects.filter(**base)

        if kwargs.pop('_distinct', False):
            queryset = queryset.distinct()

        fields = kwargs.pop('_fields', [])
        if fields:
            queryset = queryset.values(*fields)

        assert(not kwargs)

        return [model_to_dict(i) for i in queryset] if not fields else list(queryset)

    def purge(self):
        """Удаляет все фасеты для текущей ревизии
        """
        super().purge()
        Facet.objects.filter(**self.get_base_lookup()).delete()

    def count(self, **kwargs):
        base = self.get_base_lookup()
        return Facet.objects.filter(**base).count()
