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

logging.basicConfig(filename='/var/www/html/logs/user_logs.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('/user/logs/', methods=['POST', 'GET'])
@auth.login_required
def userLogs():
    es = Elasticsearch(str(elasticinfo["live"]))

    if request.method == 'POST':
        req = request.get_json()
        username = str(req['username'])
        request_start_date = req['start_date']
        request_end_date = req['end_date']
        today = datetime.utcnow().date()

        
        if not request_start_date.strip() or not request_end_date.strip():
            request_start_date = datetime(today.year, today.month, today.day, tzinfo=tz.tzutc())
            request_end_date = request_start_date + timedelta(days=1, microseconds=-1)
            request_start_date = request_start_date.isoformat()
            request_end_date = request_end_date.isoformat()
        else:
            request_start_date = parser.parse(req['start_date']).isoformat()
            request_end_date = parser.parse(req['end_date']).isoformat()
       
        if not req['cursor'].strip():
             json_payload = {
                            "size": 10,
                            "query": {
                                "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                                {"match": {"username.keyword":username}}]}
                            },
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }
        else:
            cursor = int(req['cursor'])
            json_payload = {
                            "size": 10,
                            "query": {
                                "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                                {"match": {"username.keyword":username}}]}
                            },
                            "search_after" : [cursor],
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }

        count_payload = {
                        "query": {
                            "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                            {"match": {"username.keyword":username}}]}
                        },   
                        }
                 
        results = []
        try:
            count = es.count(index="deywuro-logs-*", body=count_payload)['count']
            log_res = es.search(index="deywuro-logs-*", body=json_payload)
            for doc in log_res['hits']['hits']:
                results.append(dict(id=doc['_source']['id'],
                                   job_id=doc['_source']['job_id'],
                                    sender=doc['_source']['sender'],
                                    phone_number=doc['_source']['msisdn'],
                                    network=doc['_source']['network'],
                                    message=doc['_source']['message'],
                                    received_date=doc['_source']['submit_date'],
                                    submit_date=doc['_source']['submit_date'],
                                    delivery_date=doc['_source']['delivery_date'],
                                    status=doc['_source']['status']))
            try:
                cursor = log_res['hits']['hits'][-1]['sort'][0]
                logging.info(f"sort value:{cursor}")
            except:
                cursor = 0
                logging.info(f"sort value:{cursor}")
                
            if not len(results):
                return make_response(jsonify(code=404, error='No search results'), 200)
            else:
                logging.info('Results found')
                logging.info(results[0])
            return make_response(jsonify(code=200, cursor=cursor,
                                    doc_count=count, results=results), 200)
            
        except Exception as e:
            logging.info(e)
            return make_response(jsonify(code=500, error='search api failed'), 200)







# RESEND SMS LOGS
@app.route('/resend/logs/', methods=['POST', 'GET'])
@auth.login_required
def resendLogs():
    es = Elasticsearch(str(elasticinfo["live"]))

    if request.method == 'POST':
        req = request.get_json()
        username = str(req['username'])
        request_start_date = req['start_date']
        request_end_date = req['end_date']
        today = datetime.utcnow().date()

        
        if not request_start_date.strip() or not request_end_date.strip():
            request_start_date = datetime(today.year, today.month, today.day, tzinfo=tz.tzutc())
            request_end_date = request_start_date + timedelta(days=1, microseconds=-1)
            request_start_date = request_start_date.isoformat()
            request_end_date = request_end_date.isoformat()
        else:
            request_start_date = parser.parse(req['start_date']).isoformat()
            request_end_date = parser.parse(req['end_date']).isoformat()
       
        if not req['cursor'].strip():
             json_payload = {
                            "size": 10,
                              "query": {
                                 "bool": {
                                    "filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}}],
                                    "must": [{"match": {"username.keyword": username}},{"prefix": {"id.keyword": "resend"}}]
                                }
                               },
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }
        else:
            cursor = int(req['cursor'])
            json_payload = {
                            "size": 10,
                              "query": {
                                 "bool": {
                                    "filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}}],
                                    "must": [{"match": {"username.keyword": username}},{"prefix": {"id.keyword": "resend"}}]
                                }
                               },
                            "search_after" : [cursor],
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }
        
        count_payload = {
                           "query": {
                                 "bool": {
                                    "filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}}],
                                    "must": [{"match": {"username.keyword": username}},{"prefix": {"id.keyword": "resend"}}]
                                }
                               },

                       }
                 
        results = []
        try:
            count = es.count(index="deywuro-logs-*", body=count_payload)['count']
            log_res = es.search(index="deywuro-logs-*", body=json_payload)
            for doc in log_res['hits']['hits']:
                results.append(dict(id=doc['_source']['id'],
                                    job_id=doc['_source']['job_id'],
                                    sender=doc['_source']['sender'],
                                    phone_number=doc['_source']['msisdn'],
                                    network=doc['_source']['network'],
                                    message=doc['_source']['message'],
                                    received_date=doc['_source']['submit_date'],
                                    submit_date=doc['_source']['submit_date'],
                                    delivery_date=doc['_source']['delivery_date'],
                                    status=doc['_source']['status']))
            try:
                cursor = log_res['hits']['hits'][-1]['sort'][0]
                logging.info(f"sort value:{cursor}")
            except:
                cursor = 0
                logging.info(f"sort value:{cursor}")
                
            if not len(results):
                return make_response(jsonify(code=404, error='No search results'), 200)
            else:
                logging.info('Results found')
                logging.info(results[0])
            return make_response(jsonify(code=200, cursor=cursor,
                                    doc_count=count, results=results), 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')
