# By: Riasat Ullah
# This file contains Monday.com integration related db queries.

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


def get_monday_request_acceptance_details(conn, timestamp, organization_id, integration_key=None, account_id=None,
                                          integration_id=None):
    '''
    Get the Monday.com account details associated to a Monday.com integration.
    :param conn: db connection
    :param timestamp: timestamp when this request is being made
    :param organization_id: ID of the organization
    :param integration_key: (concealed) integration key of the integration
    :param account_id: (str) Monday.com account id
    :param integration_id: (int) the ID of the integration
    :return: (dict) -> {access_token: xxx, external_id: account id }
    '''
    assert isinstance(timestamp, datetime.datetime)
    assert isinstance(organization_id, int)

    query_params = {'timestamp': timestamp, 'org_id': organization_id}
    conditions = []
    if integration_key is not None:
        conditions.append(''' external_id in (
            select vendor_endpoint_name from service_integrations
            where start_timestamp <= %(timestamp)s
                and end_timestamp > %(timestamp)s
                and organization_id = %(org_id)s
                and integration_key = %(integ_key)s
        )''')
        query_params['integ_key'] = key_manager.unmask_reference_key(integration_key)
    if account_id is not None:
        assert isinstance(account_id, str)
        conditions.append(' external_id = %(acc_id)s ')
        query_params['acc_id'] = account_id
    if integration_id is not None:
        assert isinstance(integration_id, int)
        conditions.append(' integration_id = %(integ_id)s ')
        query_params['integ_id'] = integration_id

    query = '''
            select external_id, details->>'access_token'
            from organization_integration_type_details
            where start_timestamp <= %(timestamp)s
                and end_timestamp > %(timestamp)s
                and organization_id = %(org_id)s
                {0};
            '''.format(' and ' + ' and '.join(conditions) if len(conditions) > 0 else '')
    try:
        result = conn.fetch(query, query_params)
        if len(result) == 1:
            return {
                var_names.external_id: int(result[0][0]),
                var_names.access_token: result[0][1]
            }
        elif len(result) == 0:
            raise ValueError(errors.err_unknown_resource)
        else:
            raise SystemError(errors.err_internal_multiple_entries_found)
    except psycopg2.DatabaseError:
        raise


def get_monday_webhook_details(conn, timestamp, integration_key):
    '''
    Gets the details of a monday.com integration. This is used for incoming webhooks.
    :param conn: db connection
    :param timestamp: timestamp when this request is being made
    :param integration_key: (concealed) integration key
    :return: (tuple) (org id, service id, integration id, integration type id, additional info)
    :errors: AssertionError, DatabaseError
    '''
    assert isinstance(timestamp, datetime.datetime)
    unmasked_integ_key = key_manager.unmask_reference_key(integration_key)

    query = '''
            select sint.organization_id, sint.serviceid, sint.integration_id, sint.integration_type_id, additional_info
            from service_integrations as sint
            join integration_types as intt using(integration_type_id)
            where sint.start_timestamp <= %(timestamp)s
                and sint.end_timestamp > %(timestamp)s
                and intt.integration_type = %(integ_type)s
                and sint.integration_key = %(integ_key)s;
            '''
    query_params = {'timestamp': timestamp, 'integ_type': intt.monday, 'integ_key': unmasked_integ_key}
    try:
        result = conn.fetch(query, query_params)
        for org_id, serv_id, integ_id, integ_type_id, add_info in result:
            return org_id, serv_id, integ_id, integ_type_id, add_info
        return None
    except psycopg2.DatabaseError:
        raise
