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 userLogs():
    es = Elasticsearch(str(elasticinfo["live"]))

    if request.method == 'POST':
        req = request.get_json()
        request_search_key = str(req['search_key'])
        request_type = str(req['type'])
        cursor = req['cursor']   
        result_dict = []
        try:
            # search by username
            if request_type.lower() == "username":
                if cursor.strip():
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                     "query": {
                                         "prefix": {
                                            "username":request_search_key.lower()                          
                                    }},
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                         "prefix": {
                                            "username":request_search_key.lower()                            
                                    }},
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                    

                user_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = user_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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"]
                            )         
                    )

             # routing
            elif request_type.lower() == "route":
                if cursor.strip():
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "term": {
                                        "username.keyword": request_search_key
                                     }},
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "term": {
                                        "username.keyword": request_search_key 
                                        }},
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                    

                user_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = user_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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":
                if cursor.strip():
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                     "query": {
                                        "prefix": {
                                            "full_name":request_search_key.lower()                            
                                    }},
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                    
                else:
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                         "prefix": {
                                        "full_name":request_search_key.lower()                            
                                    }},
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                   

                full_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = full_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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 services
            elif request_type.lower() == "services":
                if not cursor.strip():
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "prefix": {"services.keyword":request_search_key}
                                    },
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "prefix": {"services.keyword":request_search_key}
                                    },
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                service_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = service_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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":
                if not cursor.strip():
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match_phrase": {"email":request_search_key}
                                    },
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match_phrase": {"email":request_search_key}
                                    },
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                email_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = email_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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":
                if not cursor.strip():
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match": {"code":request_search_key}
                                    },
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match": {"code":request_search_key}
                                    },
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                code_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = code_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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":
                if not cursor.strip():
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match": {"phone_number.keyword":request_search_key}
                                    },
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                else:
                    cursor = int(req['cursor'])
                    json_payload = {
                                    "size": 10,
                                    "query": {
                                        "match": {"phone_number.keyword":request_search_key}
                                    },
                                    "search_after" : [cursor],
                                    "sort": [
                                    { "created_at" :  "desc"}
                                    ]}
                phone_res = es.search(index="sms-users", body=json_payload)
                try:
                    cursor = phone_res['hits']['hits'][-1]['sort'][0]
                except:
                    cursor = 0
                logging.info(f"sort value:{cursor}")
                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'],
                            full_name=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 search results"), 200)
                        
                
            if result_dict == []:
                    logging.info("No search results for {}".format(request_search_key))
                    return make_response(jsonify(code=404, error="No search results"), 200)
            else:
                logging.info("found {} search results for {}".format(len(result_dict),request_search_key))
                payload = {
                    "dict" : result_dict,
                    "cursor" : cursor,
                    "total_docs" : total_docs
                }
                return make_response(jsonify(code=200, data=payload), 200)
                           
        except Exception as e:
            logging.info(e)
            return make_response(jsonify(code=500, error='search api failed'), 200)
       

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