# By: Riasat Ullah
# This file contains all constants and functions related to the Logic monitor integration.

from dbqueries.integrations import db_logic_monitor
from utils import constants, logging, var_names
import json
import requests


# Logic Monitor variables
var_agent_description = 'agent_description'
var_alert_id = 'alert_id'
var_alert_status = 'alert_status'
var_alert_type = 'alert_type'
var_data_point = 'data_point'
var_data_point_description = 'data_point_description'
var_data_source = 'data_source'
var_event_source = 'event_source'
var_group = 'group'
var_host = 'host'
var_instance = 'instance'
var_internal_id = 'internal_id'
var_level = 'level'
var_limited_message = 'limited_message'
var_message = 'message'
var_service = 'service'
var_value = 'value'

# alert status values
ack = 'ack'
active = 'active'
clear = 'clear'
test = 'test'
update = 'update'

# Internal TaskCall values
general_alert_name = 'Logic Monitor Alert'

# Logic Monitor 'level' mapped to TaskCall urgency
severity_map = {
    'critical': constants.critical_urgency,
    'error': constants.high_urgency,
    'warning': constants.medium_urgency,
    'ok': constants.low_urgency
}

# LogicMonitor url paths
url_ack_alert = 'https://{0}.logicmonitor.com/santaba/rest/alert/alerts/{1}/ack'
url_add_note = 'https://{0}.logicmonitor.com/santaba/rest/alert/alerts/{1}/note'


def update_logic_monitor_alert(conn, timestamp, org_id, integ_key, alert_id, new_state=None, new_note=None):
    '''
    Update a LogicMonitor alert.
    :param conn: db connection
    :param timestamp: timestamp when this request is being made
    :param org_id: organization ID
    :param integ_key: (concealed) key of the LogicMonitor integration
    :param alert_id: ID of the alert
    :param new_state: new state of the instance
    :param new_note: new note added to the instance
    '''
    lm_det = db_logic_monitor.get_logic_monitor_account(conn, timestamp, org_id, integ_key)
    if lm_det is None:
        return

    domain = lm_det[var_names.vendor_endpoint_name]
    api_key = lm_det[var_names.secret_token]
    headers = {'Authorization': 'Bearer ' + api_key, 'Content-Type': 'application/json', 'X-Version': '3'}

    if new_state is not None and new_state == constants.acknowledged_state and new_note is not None:
        url_to_send = url_ack_alert.format(domain, alert_id)
    elif new_note is not None:
        url_to_send = url_add_note.format(domain, alert_id)
    else:
        return

    body = {'ackComment': new_note}
    try:
        response = requests.post(url_to_send, headers=headers, data=json.dumps(body))
        if response.status_code not in [200, 201]:
            logging.error('Failed - LogicMonitor alert ' + str(alert_id) + ' update - ' + str(body))
            logging.exception(response.json())
    except Exception as e:
        logging.exception('Failed to update LogicMonitor alert')
        logging.exception(str(e))
