from django.http import HttpResponse
from django.views.generic.base import View

from staff.lib.serializers.json_serializer import JSONSerializer
from staff.apicenter.v2.utils import FieldListBuilder

ALL_CONST = 'all'


class Apiv2View(View):
    http_method_names = ('get',)
    entities = ('item',)

    default_fields = ('id',)
    related_fields = None

    serializers = {
        'json': JSONSerializer,
    }

    def dispatch(self, *args, **kwargs):
        return super(Apiv2View, self).dispatch(*args, **kwargs)

    def get(self, *args, **kwargs):
        data = self.prepare_data()
        serialized = self.serialize_data(data)
        return self._build_response(serialized)

    def prepare_data(self):
        self.fields = list(self.get_fields())
        if self.fields:
            queryset = self.queryset.values(*self.fields)
        else:
            queryset = self.queryset.none()
        return self.get_data(queryset=queryset)

    def get_fields(self):
        builder = FieldListBuilder(model=self.model, related_fields=self.related_fields)

        if self.requested_fields == ALL_CONST:
            return builder.get_model_fields()
        elif self.requested_fields:
            return builder.filter_valid_fields(self.requested_fields)
        else:
            return self.default_fields

    def get_data(self, queryset):
        raise NotImplementedError

    def serialize_data(self, data):
        serializer = self.serializers.get(self.format)
        return serializer(data, self.entities).serialize()

    def _build_response(self, serialized_data):
        if self.format == 'json':
            return HttpResponse(serialized_data, content_type='text/javascript')

    @property
    def format(self):
        return self.kwargs.get('format', 'json')

    @property
    def requested_fields(self):
        get_params = self.request.GET
        if 'fields' in get_params and get_params['fields'] == ALL_CONST:
            return ALL_CONST
        elif 'fields' in get_params:
            return get_params['fields'].split('|')
        else:
            return None


class Apiv2ListView(Apiv2View):
    """Родительский класс для apiv2-views со списком ресурсов"""

    filter_form_cls = None

    def parse_get_params(self):
        querydict = self.request.GET.copy()
        params = {'token': querydict.pop('token', None)}
        params['fields'] = querydict.pop('fields', None)
        params['filter_conditions'] = querydict
        return params

    def get_data(self, queryset):
        params = self.parse_get_params()
        if self.filter_form_cls:
            filter_form = self.filter_form_cls(params['filter_conditions'])
            queryset = filter_form.filter(queryset)
        return list(queryset)
