import logging

from intranet.search.core.sources.idm.client import IDMApiClient
from intranet.search.core.utils import reraise_as_recoverable, http
from intranet.search.core.swarm.indexer import Indexer

log = logging.getLogger(__name__)


class SourceBase(Indexer):
    """ Базовый класс индексаторов idm """

    source = None
    snippet_languages = ('ru', 'en')

    def __init__(self, *args, **kwargs):
        self.api_client = IDMApiClient()
        super().__init__(*args, **kwargs)

    @reraise_as_recoverable(*http.ERRORS)
    def do_walk(self, start_id=None, **kwargs):
        objects = self.fetch_objects(start_id=start_id)
        last_id = None
        for obj in objects:
            last_id = obj['id']
            self.next('fetch', obj=obj)
        if last_id is not None:
            self.next('walk', start_id=last_id)

    def do_create(self, obj, **kwargs):
        doc_url = self.get_doc_url(obj)
        doc_body = self.create_body(obj)
        doc = self.create_document(doc_url, updated=self.get_doc_updated(obj))
        doc.emit_body(doc_body)
        self.emit_factors(doc, obj)
        self.emit_attrs(doc, obj)

        for lang in self.snippet_languages:
            snippet = self.create_snippet(obj, lang, **kwargs)
            doc.emit_snippet(snippet, lang)

        self.next('store', document=doc, body_format='json')

    def create_snippet(self, obj, lang='ru', **kwargs):
        raise NotImplementedError()

    def fetch_objects(self, start_id=None):
        raise NotImplementedError()

    def create_body(self, obj, **kwargs):
        raise NotImplementedError()

    def do_fetch(self, obj, **kwargs):
        raise NotImplementedError()

    def get_doc_updated(self, obj):
        raise NotImplementedError()

    def do_push(self, **kwargs):
        pass

    def emit_factors(self, doc, obj):
        pass

    def emit_attrs(self, doc, obj):
        pass

    def get_doc_url(self, obj):
        return f'{self.source}:{self.get_doc_id(obj)}'

    def get_doc_id(self, obj):
        return obj['id']
