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

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


def get_freshservice_accounts(conn, timestamp, organization_id, integration_key=None):
    '''
    Get the list of Freshservice 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_params = {'timestamp': timestamp, 'org_id': organization_id, 'int_type': intt.freshservice}
    conditions = []
    if integration_key is not None:
        conditions.append('integration_key = %(integ_key)s')
        query_params['integ_key'] = key_manager.unmask_reference_key(integration_key)

    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
                {0};
            '''.format(' and ' + ' and '.join(conditions) if len(conditions) > 0 else '')
    try:
        result = conn.fetch(query, query_params)
        data = []
        for item in result:
            data.append({
                var_names.vendor_endpoint_name: item[0],
                var_names.secret_token: item[1]
            })
        return data
    except psycopg2.DatabaseError:
        raise


def update_freshservice_account(conn, timestamp, organization_id, service_ref_id, integration_key,
                                freshservice_domain, freshservice_api_key):
    '''
    Update Freshservice integration domain and api key. Ensure that an entry for a Freshservice account integration
    with the given domain exists.
    :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 freshservice_domain: domain of the Freshservice account
    :param freshservice_api_key: api key to use for the Freshservice account
    :return: (boolean) True if it exists; False otherwise
    '''
    assert isinstance(timestamp, datetime.datetime)
    assert isinstance(organization_id, int)
    assert isinstance(freshservice_domain, str)
    assert isinstance(freshservice_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 = %(frs_dom)s, secret_token = %(frs_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.freshservice,
                    'frs_dom': freshservice_domain, 'frs_apk': freshservice_api_key}
    try:
        result = conn.fetch(query, query_params)
        if len(result) == 0:
            return False
        else:
            return True
    except psycopg2.DatabaseError:
        raise
