import { createAggregateError } from '../util/errors';
import { } from 'apollo-client';
export const graphQLContent = Symbol('graphQLContent');
export interface GraphQLDocument {
    [graphQLContent]: string;
}

/**
 * Use this template string tag for all GraphQL queries.
 */
export const gql = (template: TemplateStringsArray, ...substitutions: any[]): GraphQLDocument => ({
    [graphQLContent]: String.raw(template, ...substitutions.map(s => s[graphQLContent] || s)),
});

export interface SuccessGraphQLResult<T> {
    data: T;
    errors: undefined;
}

export interface ErrorGraphQLResult {
    data: undefined;
    errors: any; /**  GQL.IGraphQLResponseError[]; */
}

export type GraphQLResult<T> = SuccessGraphQLResult<T> | ErrorGraphQLResult;


export function isGraphQLError<T>(result: GraphQLResult<T>): result is ErrorGraphQLResult {
    return !!(result as ErrorGraphQLResult).errors && (result as ErrorGraphQLResult).errors.length > 0;
}

export function dataOrThrowErrors<T>(result: GraphQLResult<T>): T {
    if (isGraphQLError(result)) {
        throw createAggregateError(result.errors);
    }
    return result.data;
}

export interface GraphQLError extends Error {
    queryName: string;
}

export const createInvalidGraphQLQueryResponseError = (queryName: string): GraphQLError =>
    Object.assign(new Error(`Invalid GraphQL response: query ${queryName}`), {
        queryName,
    });

export const createInvalidGraphQLMutationResponseError = (queryName: string): GraphQLError =>
    Object.assign(new Error(`Invalid GraphQL response: mutation ${queryName}`), {
        queryName,
    });
