# By: Riasat Ullah
# This module works with LogicMonitor integration data in the database.

from utils import integration_type_names as intt, key_manager, var_names
import datetime
import psycopg2


def get_logic_monitor_account(conn, timestamp, organization_id, integration_key):
    '''
    Get the list of LogicMonitor accounts of an organization.
    :param conn: db connection
    :param timestamp: timestamp when the request was made
    :param organization_id: the organization ID
    :param integration_key: (concealed) integration key of the integration
    :return: (list of dict) -> [{vendor_endpoint_name: full domain, secret_token: API key}, ...]
    :errors: AssertionError, DatabaseError
    '''
    assert isinstance(timestamp, datetime.datetime)
    assert isinstance(organization_id, int)

    query = '''
            select vendor_endpoint_name, secret_token
            from service_integrations as si
            join integration_types as it
                on it.integration_type_id = si.integration_type_id
                    and it.start_date <= %(timestamp)s
                    and it.end_date > %(timestamp)s
            where si.start_timestamp <= %(timestamp)s
                and si.end_timestamp > %(timestamp)s
                and si.organization_id = %(org_id)s
                and it.integration_type = %(int_type)s;
            '''

    query_params = {'timestamp': timestamp, 'org_id': organization_id, 'int_type': intt.logic_monitor,
                    'integ_key': key_manager.unmask_reference_key(integration_key)}
    try:
        result = conn.fetch(query, query_params)
        if len(result) > 0:
            return {
                var_names.vendor_endpoint_name: result[0][0],
                var_names.secret_token: result[0][1]
            }
        else:
            return None
    except psycopg2.DatabaseError:
        raise


def update_logic_monitor_account(conn, timestamp, organization_id, service_ref_id, integration_key,
                                 lm_domain, lm_api_key):
    '''
    Update the domain and api key of a LogicMonitor integration.
    :param conn: db connection
    :param timestamp: timestamp when this request is being made
    :param organization_id: ID of the organization to check against
    :param service_ref_id: (concealed) reference ID of the service the integration belongs to
    :param integration_key: (concealed) unique key for the integration
    :param lm_domain: domain of the LogicMonitor account
    :param lm_api_key: api key to use for the LogicMonitor account
    :return: (boolean) True if it exists; False otherwise
    '''
    assert isinstance(timestamp, datetime.datetime)
    assert isinstance(organization_id, int)
    assert isinstance(lm_domain, str)
    assert isinstance(lm_api_key, str)
    unmasked_serv_ref = key_manager.unmask_reference_key(service_ref_id)
    unmasked_integ_key = key_manager.unmask_reference_key(integration_key)

    query = '''
            update service_integrations set vendor_endpoint_name = %(lm_dom)s, secret_token = %(lm_apk)s
            where start_timestamp <= %(timestamp)s
                and end_timestamp > %(timestamp)s
                and organization_id = %(org_id)s
                and integration_key = %(integ_key)s
                and integration_type_id in (
                    select integration_type_id from integration_types
                    where start_date <= %(timestamp)s
                        and end_date > %(timestamp)s
                        and integration_type = %(integ_type)s
                )
                and serviceid in (
                    select serviceid from services
                    where start_timestamp <= %(timestamp)s
                        and end_timestamp > %(timestamp)s
                        and service_ref_id = %(srv_ref)s
                )
            returning vendor_endpoint_name;
            '''
    query_params = {'timestamp': timestamp, 'org_id': organization_id, 'srv_ref': unmasked_serv_ref,
                    'integ_key': unmasked_integ_key, 'integ_type': intt.logic_monitor,
                    'lm_dom': lm_domain, 'lm_apk': lm_api_key}
    try:
        result = conn.fetch(query, query_params)
        if len(result) == 0:
            return False
        else:
            return True
    except psycopg2.DatabaseError:
        raise
