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 { 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 Resource option (default: 'Gateway').
     *
     * Does not apply when `initializeNodeSDK` is `false`.
     */
    serviceName?: string;
    /**
     * Service version to use for OpenTelemetry Resource option (default: Hive Gateway version).
     *
     * Note: This can also be set by using `OTEL_SERVICE_VERSION` environment variable.
     */
    serviceVersion?: 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;
    /**
     * Sampling rate of spans. The value should be between 0 and 1.
     * By default, all spans are recorded and exported, which correspond to a sampling rate of 1.
     *
     * Note: The sampling strategy used is parent based, meaning spans will be always sampled if a sampled parent span is found in the OTEL context.
     */
    samplingRate?: number;
}
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 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>;
        /**
         * Enable/Disable cache related span events (default: true).
         */
        cache?: BooleanOrPredicate<{
            key: string;
            action: 'read' | 'write';
        }>;
        /**
         * Enable/disable schema loading spans (default: true if context manager available).
         *
         * Note: This span requires an Async compatible context manager
         */
        schema?: boolean;
        /**
         * Enable/disable initialization span (default: true).
         */
        initialization?: boolean;
    };
};
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>;

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

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