import logging

import json
from django import http
from django.http import Http404

from intranet.search.core import sources
from intranet.search.core.sources.utils import get_resource_data
from intranet.search.core.swarm.pushes import log_push, handle_indexation_push, handle_single_push
from intranet.search.api.api1.views.base import BaseApiView

log = logging.getLogger(__name__)


class RequestError(Exception):
    pass


class IndexResourceApiView(BaseApiView):
    """ API для запросов на переиндексацию ресурсов
    """

    def post(self, *args, **kwargs):
        return self.process_push()

    def put(self, *args, **kwargs):
        return self.process_push()

    def delete(self, *args, **kwargs):
        return self.process_push(action='delete')

    def process_push(self, action='create'):
        """ Обработка пришедшего пуш сообщения
        """
        search = self.kwargs['search']
        index = self.kwargs['index'] or ''
        self.validate_source(search, index)

        data = self.get_resource_data()
        push_id = log_push(data, search, index, push_type=action)

        if data.get('filters'):
            ts = data['filters'].pop('ts', None)
            keys = [f'{k}:{v}' for k, v in data['filters'].items()]
            handle_indexation_push(push_id, search=search, index=index, keys=keys, ts=ts)
        else:
            handle_single_push(push_id, search=search, index=index, data=data, action=action)
            # FIXME временный хак пока у нас существует два индексатора постов этушки:
            #  отправляем пуши в обычный индексатор ещё и в новый индексатор постов
            if search == 'at' and index == '':
                handle_single_push(push_id, search=search, index='posts', data=data, action=action)

        return http.HttpResponse(json.dumps({'status': 'ok', 'push_id': push_id}, ensure_ascii=False),
                                 content_type='text/javascript')

    def validate_source(self, search, index):
        try:
            sources.load(search, index)
        except ImportError:
            raise RequestError(f'Unknown source: {search}.{index}')

    def get_resource_data(self):
        try:
            return get_resource_data(self.request.body)
        except (ValueError, json.JSONDecodeError):
            raise RequestError('Cannot parse resource data')

    def handle_exception(self, exception):
        if isinstance(exception, Http404):
            response_class = http.HttpResponseNotFound
        elif isinstance(exception, RequestError):
            response_class = http.HttpResponseBadRequest
        else:
            response_class = http.HttpResponseServerError
        msg = {'status': 'error', 'reason': str(exception)}
        return response_class(json.dumps(msg, ensure_ascii=False), content_type='text/javascript')
