import sys
from datetime import datetime
from os import environ

from flask import request, g

from cbr_website_beta._cbr_shared.dynamo_db.DyDB__CBR_Requests import DyDB__CBR_Requests
from cbr_website_beta._cbr_shared.schemas.CBR_Request import CBR_Request
from cbr_website_beta.flask.Flask_Utils import Flask_Utils
from osbot_utils.utils.Dev import pprint
from osbot_utils.utils.Misc import date_time_now, list_set

#LOG_STATIC_FILES = True
def env_vars_to_log():
    env_vars = {'lambda': {"memory_size"        : environ.get('AWS_LAMBDA_FUNCTION_MEMORY_SIZE' ,''),
                           "function_name"      : environ.get('AWS_LAMBDA_FUNCTION_NAME'        ,''),
                           "function_version"   : environ.get('AWS_LAMBDA_FUNCTION_VERSION'     ,''),
                           "aws_region"         : environ.get('AWS_REGION'                      ,''),
                           "execution_env"      : environ.get('EXECUTION_ENV'                   ,''),
                           "amzn_trace_id"      : environ.get('_X_AMZN_TRACE_ID'                ,''),
                           "runtime"            : environ.get('AWS_EXECUTION_ENV'               ,'')}}
    return env_vars

#@xray_trace("register_logging")
def register_logging(app):
    if 'pytest' in sys.modules:
        return


    dydb_cbr_requests = DyDB__CBR_Requests()

    #todo: move this logic to the post_request so that we can capture the elapsed time
    @app.before_request
    #@xray_trace("before_request - pre_request_logging")
    def pre_request_logging():
        if Flask_Utils.is_static_request():
            return
        try:
            request._start_time = datetime.utcnow()

            if '/llms-ui' in request.path :
                return
            headers = {key: value for key, value in request.headers.items()}
            country = headers.get('Cloudfront-Viewer-Country-Name')             # todo refactor to a country and city method
            if not country:                                                     # if 'Cloudfront-Viewer-Country-Name' did not had a value
                country = headers.get('Cloudfront-Viewer-Country', 'NA')        #    try Cloudfront-Viewer-Country

        #@app.after_request
        #def post_request_logging(response):                                    # todo: refactor into helper logging class and methods

            cbr_request            = CBR_Request()
            cbr_request.user       = g.user_name         or 'NA'
            cbr_request.user_role  = f'{g.user_groups}'  or 'NA'                # todo , fix naming convention
            cbr_request.ip_address = g.ip_address        or 'NA'
            cbr_request.path       = request.path        or 'NA'
            cbr_request.date       = date_time_now(date_time_format='%Y-%m-%d')
            cbr_request.level      = "DEBUG"
            cbr_request.method     = request.method      or 'NA'
            cbr_request.referer    = request.referrer    or 'NA'
            cbr_request.headers    = headers
            cbr_request.environ    = env_vars_to_log()
            cbr_request.city       = headers.get('Cloudfront-Viewer-City'     , 'NA')
            cbr_request.country    = country
            #cbr_request.env_list   = list_set(environ)
            #cbr_request.req_id     = ???
            # cbr_request.session_id     = ???
            cbr_request.source     = 'CBR Website'


            #cbr_request.status_code= ???   #todo add this to the response section
            document = cbr_request.json()
            #pprint(document)
            dydb_cbr_requests.add_document(document)
        except Exception as e:
            pprint(e)               # todo add custom error handler which will send the errors to DyDB

        # timestamp    = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%fZ')  # ISO 8601 format
        # request_data = {"env"            : g.execution_env                      ,
        #                 "user_name"      : g.user_name                          ,
        #                 "user_groups"    : g.user_groups                        ,
        #                 #"remote_addr"   : request.remote_addr                  ,
        #                 "ip_address"     : g.ip_address                         ,
        #                 #"timestamp"     : datetime.utcnow().strftime("%d/%b/%Y %H:%M:%S"),
        #                 #"time"           : datetime.utcnow().strftime("%H:%M:%S"),
        #                 #"method"        : request.method                        ,
        #                 "path"           : request.path                          ,
        #                 "latitude"       : g.latitude                            ,
        #                 "longitude"      : g.longitude                           ,
        #                 #"scheme"        : request.scheme.upper()                ,
        #                 #"protocol"      : request.environ.get("SERVER_PROTOCOL").split("/")[-1],
        #                 }


        # todo: figure out why this takes so long to run in AWS (between 20ms to 70ms)


        #with Duration(f'cloud_watch_logs.send_log'):
        #cloud_watch_logs.send_log(log_msg)
        #with Duration(f'DyDB__Timeseries.add_document'):
        #dydb_timeseries  .add_document(log_msg, partition=g.execution_env)
        #dydb_web_requests.add_document(log_msg, partition=g.execution_env)

    # @app.after_request
    # def post_request_logging(response):
    #     if hasattr(request, "_start_time"):
    #         request_latency = datetime.utcnow() - request._start_time
    #         request_latency_seconds = request_latency.total_seconds()
    #     else:
    #         request_latency_seconds = 0
    #
    #     response_data = { "timestamp"      : datetime.utcnow().strftime("%d/%b/%Y %H:%M:%S"),
    #                       "status_code"    : response.status_code                           ,
    #                       "latency_seconds": request_latency_seconds                        }
    #     log_msg = {"source": "flask_logging" ,
    #                "type"  : 'response_data' ,
    #                "data"  : response_data  }
    #
    #     #logger.info(log_msg)
    #     cloud_watch_logs.send_log(log_msg)
    #
    #     return response