import { GraphQLError, GraphQLSchema } from 'graphql';
import type { HeadersInit } from 'node-fetch';
import { GatewayGraphQLRequestContext } from '@apollo/server-gateway-interface';
import type { Logger } from '@apollo/utils.logger';
import { GraphQLDataSource } from './datasources/types';
import { QueryPlan, QueryPlannerConfig } from '@apollo/query-planner';
import { OperationContext } from './operationContext';
import { ServiceMap } from './executeQueryPlan';
import { ServiceDefinition } from "@apollo/federation-internals";
import { Fetcher } from '@apollo/utils.fetcher';
import { OpenTelemetryConfig } from './utilities/opentelemetry';
export type ServiceEndpointDefinition = Pick<ServiceDefinition, 'name' | 'url'>;
export type Experimental_DidResolveQueryPlanCallback = ({ queryPlan, serviceMap, operationContext, requestContext, }: {
    readonly queryPlan: QueryPlan;
    readonly serviceMap: ServiceMap;
    readonly operationContext: OperationContext;
    readonly requestContext: GatewayGraphQLRequestContext;
}) => void;
interface ImplementingServiceLocation {
    name: string;
    path: string;
}
export interface CompositionMetadata {
    formatVersion: number;
    id: string;
    implementingServiceLocations: ImplementingServiceLocation[];
    schemaHash: string;
}
export type Experimental_DidFailCompositionCallback = ({ errors, serviceList, compositionMetadata, }: {
    readonly errors: GraphQLError[];
    readonly serviceList: ServiceDefinition[];
    readonly compositionMetadata?: CompositionMetadata;
}) => void;
export interface ServiceDefinitionCompositionInfo {
    serviceDefinitions: ServiceDefinition[];
    schema: GraphQLSchema;
    compositionMetadata?: CompositionMetadata;
}
export interface SupergraphSdlCompositionInfo {
    schema: GraphQLSchema;
    compositionId: string;
    supergraphSdl: string;
}
export type CompositionInfo = ServiceDefinitionCompositionInfo | SupergraphSdlCompositionInfo;
export type Experimental_DidUpdateSupergraphCallback = (currentConfig: CompositionInfo, previousConfig?: CompositionInfo) => void;
export type CompositionUpdate = ServiceDefinitionUpdate | SupergraphSdlUpdate;
export interface ServiceDefinitionUpdate {
    serviceDefinitions?: ServiceDefinition[];
    compositionMetadata?: CompositionMetadata;
    isNewSchema: boolean;
}
export interface SupergraphSdlUpdate {
    id: string;
    supergraphSdl: string;
    minDelaySeconds?: number;
}
export declare function isSupergraphSdlUpdate(update: CompositionUpdate): update is SupergraphSdlUpdate;
export declare function isServiceDefinitionUpdate(update: CompositionUpdate): update is ServiceDefinitionUpdate;
export type Experimental_UpdateServiceDefinitions = (config: DynamicGatewayConfig) => Promise<ServiceDefinitionUpdate>;
export type Experimental_UpdateSupergraphSdl = (config: DynamicGatewayConfig) => Promise<SupergraphSdlUpdate>;
export type Experimental_UpdateComposition = (config: DynamicGatewayConfig) => Promise<CompositionUpdate>;
interface GatewayConfigBase {
    debug?: boolean;
    logger?: Logger;
    __exposeQueryPlanExperimental?: boolean;
    buildService?: (definition: ServiceEndpointDefinition) => GraphQLDataSource;
    experimental_didResolveQueryPlan?: Experimental_DidResolveQueryPlanCallback;
    experimental_didUpdateSupergraph?: Experimental_DidUpdateSupergraphCallback;
    experimental_approximateQueryPlanStoreMiB?: number;
    experimental_autoFragmentization?: boolean;
    fetcher?: Fetcher;
    serviceHealthCheck?: boolean;
    queryPlannerConfig?: QueryPlannerConfig;
    telemetry?: OpenTelemetryConfig;
    validateSupergraph?: boolean;
}
export interface ServiceListGatewayConfig extends GatewayConfigBase {
    serviceList: ServiceEndpointDefinition[];
    introspectionHeaders?: HeadersInit | ((service: ServiceEndpointDefinition) => Promise<HeadersInit> | HeadersInit);
    pollIntervalInMs?: number;
}
export interface ManagedGatewayConfig extends GatewayConfigBase {
    schemaConfigDeliveryEndpoint?: string;
    uplinkEndpoints?: string[];
    uplinkMaxRetries?: number;
    pollIntervalInMs?: number;
    fallbackPollIntervalInMs?: number;
}
interface ManuallyManagedServiceDefsGatewayConfig extends GatewayConfigBase {
    experimental_updateServiceDefinitions: Experimental_UpdateServiceDefinitions;
    pollIntervalInMs?: number;
}
interface ExperimentalManuallyManagedSupergraphSdlGatewayConfig extends GatewayConfigBase {
    experimental_updateSupergraphSdl: Experimental_UpdateSupergraphSdl;
    pollIntervalInMs?: number;
}
export declare function isManuallyManagedSupergraphSdlGatewayConfig(config: GatewayConfig): config is ManuallyManagedSupergraphSdlGatewayConfig;
export type SupergraphSdlUpdateFunction = (updatedSupergraphSdl: string) => void;
export type SubgraphHealthCheckFunction = (supergraphSdl: string) => Promise<void>;
export type GetDataSourceFunction = ({ name, url, }: ServiceEndpointDefinition) => GraphQLDataSource;
export interface SupergraphSdlHookOptions {
    update: SupergraphSdlUpdateFunction;
    healthCheck: SubgraphHealthCheckFunction;
    getDataSource: GetDataSourceFunction;
}
export interface SupergraphSdlHook {
    (options: SupergraphSdlHookOptions): Promise<{
        supergraphSdl: string;
        cleanup?: () => Promise<void>;
    }>;
}
export interface SupergraphManager {
    initialize: SupergraphSdlHook;
}
type ManuallyManagedSupergraphSdlGatewayConfig = SupergraphSdlHookGatewayConfig | SupergraphManagerGatewayConfig;
export interface SupergraphSdlHookGatewayConfig extends GatewayConfigBase {
    supergraphSdl: SupergraphSdlHook;
}
export interface SupergraphManagerGatewayConfig extends GatewayConfigBase {
    supergraphSdl: SupergraphManager;
}
type ManuallyManagedGatewayConfig = ManuallyManagedServiceDefsGatewayConfig | ExperimentalManuallyManagedSupergraphSdlGatewayConfig | ManuallyManagedSupergraphSdlGatewayConfig | ServiceListGatewayConfig;
interface LocalGatewayConfig extends GatewayConfigBase {
    localServiceList: ServiceDefinition[];
}
interface StaticSupergraphSdlGatewayConfig extends GatewayConfigBase {
    supergraphSdl: string;
}
export type StaticGatewayConfig = LocalGatewayConfig | StaticSupergraphSdlGatewayConfig;
export type DynamicGatewayConfig = ManagedGatewayConfig | ManuallyManagedGatewayConfig;
export type GatewayConfig = StaticGatewayConfig | DynamicGatewayConfig;
export declare function isLocalConfig(config: GatewayConfig): config is LocalGatewayConfig;
export declare function isServiceListConfig(config: GatewayConfig): config is ServiceListGatewayConfig;
export declare function isStaticSupergraphSdlConfig(config: GatewayConfig): config is StaticSupergraphSdlGatewayConfig;
export declare function isSupergraphSdlHookConfig(config: GatewayConfig): config is SupergraphSdlHookGatewayConfig;
export declare function isSupergraphManagerConfig(config: GatewayConfig): config is SupergraphManagerGatewayConfig;
export declare function isManuallyManagedConfig(config: GatewayConfig): config is ManuallyManagedGatewayConfig;
export declare function isManagedConfig(config: GatewayConfig): config is ManagedGatewayConfig;
export declare function isStaticConfig(config: GatewayConfig): config is StaticGatewayConfig;
export {};
//# sourceMappingURL=config.d.ts.map