# -*- coding: utf-8 -*-
# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""elasticsearch search views"""
from elasticsearch import Elasticsearch
from elasticsearch.exceptions import NotFoundError
from elasticsearch_dsl import Search
from bs4 import BeautifulSoup

from logilab.mtconverter import xml_escape

from cubicweb.view import StartupView

from cubes.elasticsearch.es import indexable_types


class ElasticSearchView(StartupView):
    __regid__ = "esearch"

    def call(self, **kwargs):
        search_comp = self._cw.vreg['components'].select_or_none('search-comp',
                                                                 self._cw)
        if search_comp:
            search_comp.render(w=self.w)

        self.w(u'<h1>%s</h1>' % self._cw._('Recherche'))
        query_string = xml_escape(self._cw.form.get('search', ''))
        self.w(u'<h2>Résultats pour : <em>%s</em></h2>' % query_string)
        locations = self._cw.vreg.config['elasticsearch-locations']
        index_name = self._cw.vreg.config['index-name']
        # TODO sanitize locations
        # TODO create a es objet/connexion outside of each request and reuse it
        if locations:
            es = Elasticsearch(locations.split(','))
        else:
            es = Elasticsearch()
        search = Search(using=es, index=index_name,
                        doc_type=indexable_types(self._cw.vreg.schema)) \
                        .query('multi_match',  # noqa
                               query=query_string,
                               fields=("title^3", "name^3", "content^2", "_all",)) \
                        .highlight('content') \
                        .highlight_options(pre_tags="",
                                           post_tags="",
                                           fragment_size=150)
        try:
            response = search.execute()
        except NotFoundError:
            self.w(u'index not found in elasticsearch')
            return
        self.w(u'Resultats: %s' % response.hits.total)
        self.w(u'<ul>')
        for result in response:
            self.w(u'<li>')
            infos = result.to_dict()
            infos['_score'] = result.meta.score
            infos['keys'] = result.to_dict().keys()
            infos.setdefault('title', infos.get('name', infos.get('reference', u'n/a')))
            try:
                self.w(u'<a href="%(cwuri)s">%(title)s</a> (%(_score).2f)<br/>' % (infos))
                if self._cw.form.get('debug-es'):
                    self.w(u' [%(keys)s] <br/>' % infos)
            except KeyError:
                self.w(u'Missing key in : %s' % infos.keys())
            try:
                for fragment in result.meta.highlight.content:
                    self.w(u'... %s' % BeautifulSoup(fragment, 'lxml').get_text())
                    self.w(u' ... <br/>')
            except AttributeError:
                pass
            self.w(u'</li>')
        self.w(u'</ul>')