import elasticsearch
from flask import Flask, request, make_response, jsonify
from flask_httpauth import HTTPBasicAuth
import logging
import datetime
from datetime import datetime
import json
from elasticsearch import Elasticsearch, helpers
import re
from configparser import ConfigParser

logging.basicConfig(filename='/var/www/html/logs/search_users.log',
                    filemode='a',
                    format='%(asctime)s %(name)s %(levelname)s %(message)s',
                    level=logging.INFO)
app = Flask(__name__)
#Read config.ini file
config_object = ConfigParser()
config_object.read("config.ini")

#Get info
elasticinfo = config_object["elastic"]
authinfo = config_object["auth"]
auth = HTTPBasicAuth()

USER_DATA = {
    str(authinfo["username"]): str(authinfo["password"])
}

@auth.verify_password
def verify(username, password):
    if not (username and password):
        return False
    return USER_DATA.get(username) == password

@app.route('/details/search/', methods=['POST', 'GET'])
@auth.login_required
def search():
    es = Elasticsearch(str(elasticinfo["live"]))

    if request.method == 'POST':
        req = request.get_json()
        request_search_key = req['search_key']
        request_type = req['type']
        request_scroll_id = req['_scroll_id']
        #code_key = re.sub('[\*@#$]', '', request_search_key)
        result_dict = []
        try:
            # search by services
            
            if request_type.lower() == "services":
                json_payload={"size":10,"query":{"prefix" : {"services": "{}".format(request_search_key)}}}
                try:
                    service_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = service_res['_scroll_id']
                    total_docs = service_res['hits']['total']['value']
                    results = service_res['hits']['hits']

                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                    
                except:
                    service_res = es.search(index="hellio-deywuro-users-*", 
                                            body=json_payload, scroll="5m")
                    if service_res['hits']['hits'] == []:
                        json_payload = {
                        "size": 10,
                        "query":{"bool": 
                                    {"must":[
                                        {"term":{"services.keyword":"{}".format(request_search_key)}}
                                        ]}},
                                    }
                        service_res = es.search(index="hellio-deywuro-users-*", 
                                                body=json_payload, scroll="5m")
                    _scroll_id = service_res['_scroll_id']
                    total_docs = service_res['hits']['total']['value']
                    results = service_res['hits']['hits']
                    
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                   

        

            # search by code
            elif request_type.lower() == "code":
                try:
                    code_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = code_res['_scroll_id']
                    total_docs = code_res['hits']['total']['value']
                    results = code_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                    
                except:
                    code_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match" : {"code.keyword": "{}".format(request_search_key)}}}, scroll="5m")
                      
                                
                    if code_res['hits']['hits'] == []:
                         code_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"code": "{}".format(request_search_key)}}}, scroll="5m")   
                        
                    _scroll_id = code_res['_scroll_id']
                    total_docs = code_res['hits']['total']['value']
                
                    results = code_res['hits']['hits']
                    
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                    
            
                
            # search by username
            elif request_type.lower() == "username":
                try:
                    user_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = user_res['_scroll_id']
                    total_docs = user_res['hits']['total']['value']
                    results = user_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                   
                except:
                    user_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"username.keyword": "{}".format(request_search_key)}}}, scroll="5m")
                    if user_res['hits']['hits'] == []:
                        user_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match" : {"username": "{}".format(request_search_key)}}}, scroll="5m")
                      
                    if user_res['hits']['hits'] == []:
                        user_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"prefix" : {"username": "{}".format(request_search_key)}}}, scroll="5m")
                    if user_res['hits']['hits'] == []:
                        user_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match" : {"username": ".*{}*.".format(request_search_key)}}}, scroll="5m")
                             
                    if user_res['hits']['hits'] == []:
                        user_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match_phrase" : {"username.keyword": "{}".format(request_search_key)}}}, scroll="5m")      
                    _scroll_id = user_res['_scroll_id']
                    total_docs = user_res['hits']['total']['value']
                    results = user_res['hits']['hits']
                    
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                  
                    
                        

            # search by fullname
            elif request_type.lower() == "fullname":
                try:
                    full_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = full_res['_scroll_id']
                    total_docs = full_res['hits']['total']['value']
                    results = full_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                    
                except:
                    full_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"full_name.keyword": "{}".format(request_search_key)}}}, scroll="5m")
                    if full_res['hits']['hits'] == []:    
                         full_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match" : {"full_name": "{}".format(request_search_key)}}}, scroll="5m")
                   
                    if full_res['hits']['hits'] == []:    
                         full_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"prefix" : {"full_name": "{}".format(request_search_key)}}}, scroll="5m") 
                    if full_res['hits']['hits'] == []:    
                        full_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"full_name": ".*{}*.".format(request_search_key)}}}, scroll="5m")
                        
                    if full_res['hits']['hits'] == []:
                        full_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match_phrase" : {"full_name": "{}".format(request_search_key)}}}, scroll="5m")      
                    _scroll_id = full_res['_scroll_id']
                    total_docs = full_res['hits']['total']['value']
                
                    results = full_res['hits']['hits']
                    
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                        )
                 
                                    

            # search by email
            elif request_type.lower() == "email":
                try:
                    email_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = email_res['_scroll_id']
                    total_docs = email_res['hits']['total']['value']
                    results = email_res['hits']['hits']
                    
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                   
                except:
                    email_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match" : {"email.keyword": "{}".format(request_search_key)}}}, scroll="5m")
                    if email_res['hits']['hits'] == []:
                        email_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"email": "{}".format(request_search_key)}}}, scroll="5m")
                        
                    if email_res['hits']['hits'] == []:
                        email_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match_phrase" : {"email": "{}".format(request_search_key)}}}, scroll="5m")      
                    _scroll_id = email_res['_scroll_id']
                    total_docs = email_res['hits']['total']['value']
                
                    results = email_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                    
                
                    
            
            # search by phonenumber
            elif request_type.lower() == "phonenumber":
                try:
                    phone_res = es.scroll(scroll_id=request_scroll_id, scroll='5m')
                    _scroll_id = phone_res['_scroll_id']
                    total_docs = phone_res['hits']['total']['value']
                    results = phone_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                 

                except:
                    phone_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match" : {"phone_number.keyword": "{}".format(request_search_key)}}}, scroll="5m")
                    if phone_res['hits']['hits'] == []:
                        phone_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"phone_number": "{}".format(request_search_key)}}}, scroll="5m")
                    if phone_res['hits']['hits'] == []:
                        phone_res = es.search(index="hellio-deywuro-users-*",
                                    body={"size":10,"query":{"match": {"phone_number": ".*{}*.".format(request_search_key)}}}, scroll="5m")
                    if phone_res['hits']['hits'] == []:
                        phone_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match_phrase" : {"phone_number": "{}".format(request_search_key)}}}, scroll="5m")
                    if phone_res['hits']['hits'] == []:
                        phone_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"prefix" : {"phone_number": "{}".format(request_search_key)}}}, scroll="5m") 
                    if phone_res['hits']['hits'] == []:
                        phone_res = es.search(index="hellio-deywuro-users-*",
                                        body={"size":10,"query":{"match_phrase" : {"phone_number": ".*{}*.".format(request_search_key)}}}, scroll="5m")     
                    _scroll_id = phone_res['_scroll_id']
                    total_docs = phone_res['hits']['total']['value']
            
                    results = phone_res['hits']['hits']
                    for i, doc in enumerate(results):
                        result_dict.append(
                            dict(id=doc['_source']['id'],
                            username=doc['_source']['username'],
                            fullname=doc['_source']['full_name'],
                            created_at=doc['_source']['created_at'],
                            deleted_at=doc['_source']['deleted_at'],
                            updated_at = doc['_source']['updated_at'],
                            status = doc['_source']['status'],
                            phone_number = doc['_source']['phone_number'],
                            email = doc['_source']['email'],
                            services = doc["_source"]["services"],
                            code = doc["_source"]["code"]
                            )         
                    )
                  
                
            else:
                logging.info("No search parameters")
                return make_response(jsonify(code=404, error="No matching searches"), 200)
                        
                
            if result_dict == []:
                    logging.info("No matching results for {}".format(request_search_key))
                    return make_response(jsonify(code=404, error="No matching searches"), 200)
            else:
                logging.info("found {} matching results for {}".format(len(result_dict),request_search_key))
                payload = {
                    "dict" : result_dict,
                    "_scroll_id" : _scroll_id,
                    "total_docs" : total_docs
                }
                return make_response(jsonify(code=200, data=payload), 200)
        except Exception as e:
            logging.info("Search Api failed with, [error: {}]".format(e))
            return make_response(jsonify(code=500, error='Search Api failed'), 200)


if __name__ == '__main__':
    app.run(host='0.0.0.0')
