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

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

    if request.method == 'POST':
        req = request.get_json()
        request_search_key = req['username']
        request_type = req['system_type']
        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()

        try:

            if request_type.lower() == "all":
                json_payload ={
                    "size":0,
                    "query":{"bool":{"filter":[{"range":{"submit_time":{"gte":"{}".format(request_start_date),"lte":"{}".format(request_end_date)}}},
                    {"query_string":{"query":"*"}}],
                    "must":[{"match_phrase":{"username":{"query":"{}".format(request_search_key)}}}]}},
                    "aggs":{"2":{"filters":{"filters":{"*":{"query_string":{"query":"*"}}}},"aggs":{}}}}


                 

                api_res = es.search(index="api-sms-submit-*", body=json_payload)
                results = api_res['aggregations']['2']['buckets']['*']['doc_count']


            
            else:
                json_payload ={
                    "size":0,
                    "query":{"bool":{"filter":[{"range":{"submit_time":{"gte":"{}".format(request_start_date),"lte":"{}".format(request_end_date)}}},
                    {"query_string":{"query":"*"}}],
                    "must":[{"match_phrase":{"username":{"query":"{}".format(request_search_key)}}},
                    {"match_phrase":{"system_type":{"query":"{}".format(request_type)}}}]}},
                    "aggs":{"2":{"filters":{"filters":{"*":{"query_string":{"query":"*"}}}},
                    "aggs":{}}}}

                api_res = es.search(index="api-sms-submit-*", body=json_payload)
                results = api_res['aggregations']['2']['buckets']['*']['doc_count']

                                
            if not results:
                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(results,request_search_key))
                return make_response(jsonify(code=200, total_count=results), 200)
        except Exception as e:
            logging.info(e)
            return make_response(jsonify(code=500, error='search failed'), 200)
        


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