import { ContextManager, Tracer, DiagLogLevel, Context } from '@opentelemetry/api';
import { GatewayConfigContext, GatewayPlugin } from '@graphql-hive/gateway-runtime';
import { MaybePromise, ExecutionRequest } from '@graphql-tools/utils';
import { SpanProcessor, BufferConfig } from '@opentelemetry/sdk-trace-base';
import { AzureMonitorExporterOptions } from '@azure/monitor-opentelemetry-exporter';
import { ExporterConfig } from '@opentelemetry/exporter-zipkin';
import { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
import { OTLPGRPCExporterConfigNode } from '@opentelemetry/otlp-grpc-exporter-base';
import { MaybePromise as MaybePromise$1 } from '@whatwg-node/promise-helpers';

type BooleanOrPredicate<TInput = never> = boolean | ((input: TInput) => boolean);
interface OpenTelemetryGatewayPluginOptionsWithoutInit {
    /**
     * Whether to initialize the OpenTelemetry SDK (default: true).
     */
    initializeNodeSDK: false;
    /**
     * Whether to rely on OTEL context api for span correlation.
     *  - `true`: the plugin will rely on OTEL context manager for span parenting.
     *  - `false`: the plugin will rely on request context for span parenting,
     *    which implies that parenting with user defined may be broken.
     *
     * By default, it is enabled if the registered Context Manager is compatible with async calls,
     * or if it is possible to register an `AsyncLocalStorageContextManager`.
     *
     * Note: If `true`, an error is thrown if it fails to obtain an async calls compatible Context Manager.
     */
    contextManager?: boolean;
}
interface OpenTelemetryGatewayPluginOptionsWithInit {
    /**
     * Whether to initialize the OpenTelemetry SDK (default: true).
     */
    initializeNodeSDK?: true;
    /**
     * A list of OpenTelemetry exporters to use for exporting the spans.
     * You can use exporters from `@opentelemetry/exporter-*` packages, or use the built-in utility functions.
     *
     * Does not apply when `initializeNodeSDK` is `false`.
     */
    exporters: MaybePromise<SpanProcessor>[];
    /**
     * Service name to use for OpenTelemetry NodeSDK resource option (default: 'Gateway').
     *
     * Does not apply when `initializeNodeSDK` is `false`.
     */
    serviceName?: string;
    /**
     * Whether to rely on OTEL context api for span correlation.
     *  - `undefined` (default): the plugin will try to enable context manager if possible.
     *  - `false`: the plugin will rely on request context for span parenting,
     *             which implies that any user defined context and spans will be ignored.
     *  - `true`: the plugin will rely on AsyncLocalStorage based context manager.
     *            Note that `async_hooks` module must be available, otherwise provide a custom `ContextManager` instance.
     *  - `ContextManager`: rely on this provided `ContextManger` instance.
     */
    contextManager?: ContextManager | boolean;
}
type OpenTelemetryGatewayPluginOptionsInit = OpenTelemetryGatewayPluginOptionsWithInit | OpenTelemetryGatewayPluginOptionsWithoutInit;
type OpenTelemetryGatewayPluginOptions = OpenTelemetryGatewayPluginOptionsInit & {
    /**
     * Tracer instance to use for creating spans (default: a tracer with name 'gateway').
     */
    tracer?: Tracer;
    /**
     * Whether to inherit the context from the calling service (default: true).
     *
     * This process is done by extracting the context from the incoming request headers. If disabled, a new context and a trace-id will be created.
     *
     * See https://opentelemetry.io/docs/languages/js/propagation/
     */
    inheritContext?: boolean;
    /**
     * Whether to propagate the context to the outgoing requests (default: true).
     *
     * This process is done by injecting the context into the outgoing request headers. If disabled, the context will not be propagated.
     *
     * See https://opentelemetry.io/docs/languages/js/propagation/
     */
    propagateContext?: boolean;
    /**
     * The level of verbosity of OTEL diagnostic logs.
     * @default Verbose
     */
    diagLevel?: DiagLogLevel;
    /**
     * Options to control which spans to create.
     * By default, all spans are enabled.
     *
     * You may specify a boolean value to enable/disable all spans, or a function to dynamically enable/disable spans based on the input.
     */
    spans?: {
        /**
         * Enable/disable Spans of internal introspection queries in proxy mode (default: true).
         */
        introspection?: BooleanOrPredicate<{
            executionRequest: ExecutionRequest;
            subgraphName: string;
        }>;
        /**
         * Enable/disable HTTP request spans (default: true).
         *
         * Disabling the HTTP span will also disable all other child spans.
         */
        http?: BooleanOrPredicate<{
            request: Request;
        }>;
        /**
         * Enable/disable GraphQL operation spans (default: true).
         *
         * Disabling the GraphQL operation spa will also disable all other child spans.
         */
        graphql?: BooleanOrPredicate<unknown>;
        /**
         * Enable/disable GraphQL context building phase (default: true).
         */
        graphqlContextBuilding?: BooleanOrPredicate<unknown>;
        /**
         * Enable/disable GraphQL parse spans (default: true).
         */
        graphqlParse?: BooleanOrPredicate<unknown>;
        /**
         * Enable/disable GraphQL validate spans (default: true).
         */
        graphqlValidate?: BooleanOrPredicate<unknown>;
        /**
         * Enable/disable GraphQL execute spans (default: true).
         *
         * Disabling the GraphQL execute spans will also disable all other child spans.
         */
        graphqlExecute?: BooleanOrPredicate<unknown>;
        /**
         * Enable/disable subgraph execute spans (default: true).
         *
         * Disabling the subgraph execute spans will also disable all other child spans.
         */
        subgraphExecute?: BooleanOrPredicate<{
            executionRequest: ExecutionRequest;
            subgraphName: string;
        }>;
        /**
         * Enable/disable upstream HTTP fetch calls spans (default: true).
         */
        upstreamFetch?: BooleanOrPredicate<ExecutionRequest | undefined>;
    };
};
type OpenTelemetryContextExtension = {
    opentelemetry: {
        tracer: Tracer;
        activeContext: () => Context;
    };
};
type OpenTelemetryPlugin = GatewayPlugin<OpenTelemetryContextExtension> & {
    getOtelContext: (payload: {
        request?: Request;
        context?: any;
        executionRequest?: ExecutionRequest;
    }) => Context;
    getTracer(): Tracer;
};
declare function useOpenTelemetry(options: OpenTelemetryGatewayPluginOptions & {
    logger: GatewayConfigContext['logger'];
}): OpenTelemetryPlugin;

type BatchingConfig = boolean | BufferConfig;
declare function createStdoutExporter(batchingConfig?: BatchingConfig): SpanProcessor;
declare function createZipkinExporter(config: ExporterConfig, batchingConfig?: BatchingConfig): SpanProcessor;
declare function createOtlpHttpExporter(config: OTLPExporterNodeConfigBase, batchingConfig?: BatchingConfig): SpanProcessor;
declare function createOtlpGrpcExporter(config: OTLPGRPCExporterConfigNode, batchingConfig?: BatchingConfig): MaybePromise$1<SpanProcessor>;
declare function createAzureMonitorExporter(config: AzureMonitorExporterOptions, batchingConfig?: BatchingConfig): MaybePromise$1<SpanProcessor>;

type OpenTelemetryMeshPluginOptions = OpenTelemetryGatewayPluginOptions;
declare const OpenTelemetryDiagLogLevel: typeof DiagLogLevel;

export { type BatchingConfig, OpenTelemetryDiagLogLevel, type OpenTelemetryGatewayPluginOptions, type OpenTelemetryMeshPluginOptions, type OpenTelemetryPlugin, createAzureMonitorExporter, createOtlpGrpcExporter, createOtlpHttpExporter, createStdoutExporter, createZipkinExporter, useOpenTelemetry };
