# By: Riasat Ullah
# This file contains functions that are used to log details of alert related communications sent out
# and received from users. These logs will help us understand the type of usage of each user, how much cost
# we are incurring for each user and reconcile with the text and call dispatching companies.

from dbqueries import db_api_keys, db_task_instances
from threading import Thread
from utils import constants, logging, times
from utils.db_connection import CONN_POOL


class AlertLogger(Thread):
    '''
    This is an alert logger thread class.
    '''
    def __init__(self, conn, alert_logs):
        self.conn = conn
        self.alert_logs = alert_logs
        Thread.__init__(self, name='AlertLogger_' + times.get_current_timestamp().strftime(constants.timestamp_format))

    def run(self):
        logging.info(self.name + ' - Running alert logger..')
        try:
            db_task_instances.log_alert_events(self.conn, self.alert_logs)
        except Exception as e:
            logging.exception(str(e))
            logging.warning('Not raising the exception. Passing it through...')
            pass


class ApiCallLogger(Thread):
    '''
    This is an API call logger thread class.
    '''
    def __init__(self, conn, timestamp, org_id, api_key_id, api_version, event_type=None, instance_id=None,
                 denied=None, log=None):
        '''
        Logs api calls.
        :param conn: db connection
        :param timestamp: timestamp this request is being made on
        :param org_id: ID of the organization the api key belongs to
        :param api_key_id: ID of the api key
        :param api_version: the version/type of API this log is for
        :param event_type: the type of event the call was made for
        :param instance_id: instance ID the call was made for
        :param denied: (boolean) True if the call was denied
        :param log: (optional) any log for the call
        '''
        self.conn = CONN_POOL.get_db_conn() if conn is None else conn
        self.received_conn = False if conn is None else True
        self.timestamp = timestamp
        self.org_id = org_id
        self.api_key_id = api_key_id
        self.api_version = api_version
        self.event_type = event_type
        self.instance_id = instance_id
        self.denied = denied
        self.log = log
        Thread.__init__(self)

    def run(self):
        logging.info('Running api call logger..')
        try:
            db_api_keys.log_api_call(self.conn, self.timestamp, self.org_id, self.api_key_id, self.api_version,
                                     event_type=self.event_type, instance_id=self.instance_id,
                                     denied=self.denied, log=self.log)
        except Exception as e:
            logging.exception(str(e))
            logging.warning('Not raising the exception. Passing it through...')
            pass
        finally:
            if not self.received_conn:
                CONN_POOL.put_db_conn(self.conn)
