import json
import requests
from san.api_config import ApiConfig
from san.env_vars import SANBASE_GQL_HOST
from san.error import SanError


def execute_gql(gql_query_str):
    headers = {}
    if ApiConfig.api_key:
        headers = {'authorization': "Apikey {}".format(ApiConfig.api_key)}

    try:
        response = requests.post(
            SANBASE_GQL_HOST,
            json={'query': gql_query_str},
            headers=headers)
    except requests.exceptions.RequestException as e:
        raise SanError('Error running query: ({})'.format(e))

    if response.status_code == 200:
        return __handle_success_response__(response, gql_query_str)
    else:
        if __result_has_gql_errors__(response):
            error_response = response.json()['errors']['details']
        else:
            error_response = ''
        raise SanError(
            "Error running query. Status code: {}.\n {}\n {}".format(
                response.status_code,
                error_response,
                gql_query_str))


def __handle_success_response__(response, gql_query_str):
    if __result_has_gql_errors__(response):
        raise SanError(
            "GraphQL error occured running query {} \n errors: {}".format(
                gql_query_str,
                response.json()['errors']))
    elif __exist_not_empty_result(response):
        return response.json()['data']
    else:
        raise SanError(
            "Error running query. Status code: {}.\n {}" .format(
                response.status_code,
                gql_query_str))


def __result_has_gql_errors__(response):
    return 'errors' in response.json().keys()


def __exist_not_empty_result(response):
    return 'data' in response.json().keys() and len(
        list(
            filter(
                lambda x: x is not None,
                response.json()['data'].values()))) > 0
