# -*- coding: utf-8 -*-
import json
import requests
from bottle import request
from elasticsearch import RequestsHttpConnection, Elasticsearch as ES

from mining.utils.listc import listc_dict


class Elasticsearch(object):

    _search = True

    def conn(self):
        """Open connection on Elasticsearch DataBase"""
        conn = ES([{"host": self.conf.get('host'),
                    "port": int(self.conf.get('port'))}],
                  connection_class=RequestsHttpConnection)
        return conn

    def _bulk(self, bulk):
        requests.post("http://{}:{}/_bulk".format(
            self.conf.get('host'), self.conf.get('port')),
            headers={'content-type': 'application/json'},
            data=bulk)

    def save(self, house, data, content_type='dict'):
        """Save meta dada on Elasticsearch"""
        requests.delete("http://{}:{}/{}".format(
            self.conf.get('host'), self.conf.get('port'), house))
        bulk = ""
        for i, obj in enumerate(data.get('data')):
            bulk += "{}\n".format(json.dumps({"index":
                                              {"_index": house,
                                               "_type": "data"}}))
            bulk += "{}\n".format(json.dumps(obj))

            if i % 1000 == 0:
                self._bulk(bulk)
                bulk = ""
        self._bulk(bulk)
        self.conn().index(index=house,
                          doc_type='columns',
                          body={"columns": data.get('columns')})
        return self.conn()

    def get(self, house, filters=None, page=1, content_type="dict",
            callback={}):
        """Get meta data on Elasticsearch"""
        doc_args = {"size": 50, "from_": page - 1}
        if not page:
            doc_args = {}
        count = self.conn().count(
            index=house, doc_type="data",
            body=self.filter(filters=filters)).get('count')
        doc_data = self.conn().search(index=house, doc_type='data',
                                      body=self.filter(filters=filters),
                                      **doc_args)
        data = {}
        data['data'] = listc_dict(doc_data.get('hits').get('hits'), "_source")
        doc_columns = self.conn().search(index=house, doc_type='columns',
                                         body=self.filter())
        data.update(doc_columns.get('hits').get('hits')[0].get('_source'))
        data['count'] = count
        return data

    def filter(self, filters=[]):
        """Generate dict to applay filter on Elasticsearch
        should: OR
        must: AND
        """
        filter = {
            "query": {
                "filtered": {
                    "query": {
                        "bool": {
                            "must": []
                        }
                    },
                    "filter": {
                        "bool": {
                            "must": []
                        }
                    }
                }
            }
        }
        filtered_query = filter['query']["filtered"]["query"]['bool']['must']
        filtered_filter = filter['query']["filtered"]["filter"]['bool']['must']

        if len(filters) >= 1:
            for f in filters:
                s = f.split('__')
                field = s[1]
                operator = s[2]
                value = request.GET.get(f)
                if operator == 'is':
                    filter_type = "match"
                    filter_obj = filtered_query
                    if len(value.split(" ")) == 1:
                        filter_type = "term"
                        filter_obj = filtered_filter
                        if type(value) in [str, unicode]:
                            value = value.lower()

                    filter_obj.append({filter_type: {field: value}})
                """
                if operator == 'like':
                    df = df[df[field].str.contains(value)]
                elif operator == 'regex':
                    df = DataFrameSearchColumn(df, field, value, operator)
                else:
                    df = df.query(df_generate(df, value, f))
                """
            return filter
        return {"query": {"match_all": {}}}

@@ -189,58 +189,109 @@
 ict%0A
-%0A%0Aclass Elasticsearch(object):%0A%0A    _search = True
+from mining.db.datawarehouse import GenericDataWarehouse%0A%0A%0Aclass Elasticsearch(GenericDataWarehouse):
 %0A%0A  
@@ -296,20 +296,24 @@
     def 
-conn
+__init__
 (self):%0A
@@ -372,24 +372,102 @@
 %22%22%22%0A        
+super(Elasticsearch, self).__init__()%0A        self.search = True%0A        self.
 conn = ES(%5B%7B
@@ -497,16 +497,21 @@
 host'),%0A
+     
         
@@ -578,16 +578,21 @@
         
+     
 connecti
@@ -636,19 +636,69 @@
     
-return conn
+self.base_url = self.conn.transport.get_connection().base_url
 %0A%0A  
@@ -745,26 +745,16 @@
 s.post(%22
-http://%7B%7D:
 %7B%7D/_bulk
@@ -766,65 +766,21 @@
 mat(
-%0A            self.conf.get('host'), self.conf.get('port')
+self.base_url
 ),%0A 
@@ -989,18 +989,8 @@
 te(%22
-http://%7B%7D:
 %7B%7D/%7B
@@ -1003,65 +1003,21 @@
 mat(
-%0A            self.conf.get('host'), self.conf.get('port')
+self.base_url
 , ho
@@ -1460,18 +1460,16 @@
 elf.conn
-()
 .index(i
@@ -1476,26 +1476,24 @@
 ndex=house,%0A
-  
             
@@ -1516,34 +1516,32 @@
 type='columns',%0A
-  
                 
@@ -1611,18 +1611,16 @@
 elf.conn
-()
 %0A%0A    de
@@ -1650,12 +1650,10 @@
 ers=
-None
+%5B%5D
 , pa
@@ -1873,18 +1873,16 @@
 elf.conn
-()
 .count(%0A
@@ -2003,34 +2003,32 @@
 data = self.conn
-()
 .search(index=ho
@@ -2077,34 +2077,32 @@
                 
-  
 body=self.filter
@@ -2120,18 +2120,16 @@
 lters),%0A
-  
         
@@ -2296,18 +2296,16 @@
 elf.conn
-()
 .search(
@@ -2329,34 +2329,32 @@
 type='columns',%0A
-  
                 

upgrade elasticsearch GenericDataWarehouse