import { Reporter } from "./reporter.cjs";
import { Maybe, Plugin, YogaInitialContext, YogaLogger, YogaServer } from "graphql-yoga";
import { calculateReferencedFieldsByType } from "@apollo/utils.usagereporting";
import { ApolloInlineGraphqlTraceContext, ApolloInlineRequestTraceContext, ApolloInlineTracePluginOptions } from "@graphql-yoga/plugin-apollo-inline-trace";

//#region src/index.d.ts
type ApolloUsageReportOptions = ApolloInlineTracePluginOptions & {
  /**
   * The graph ref of the managed federation graph.
   * It is composed of the graph ID and the variant (`<YOUR_GRAPH_ID>@<VARIANT>`).
   *
   * If not provided, `APOLLO_GRAPH_REF` environment variable is used.
   *
   * You can find a a graph's ref at the top of its Schema Reference page in Apollo Studio.
   */
  graphRef?: string;
  /**
   * The API key to use to authenticate with the managed federation up link.
   * It needs at least the `service:read` permission.
   *
   * If not provided, `APOLLO_KEY` environment variable will be used instead.
   *
   * [Learn how to create an API key](https://www.apollographql.com/docs/federation/v1/managed-federation/setup#4-connect-the-gateway-to-studio)
   */
  apiKey?: string;
  /**
   * Usage report endpoint
   *
   * Defaults to GraphOS endpoint (https://usage-reporting.api.apollographql.com/api/ingress/traces)
   */
  endpoint?: string;
  /**
   * Agent Version to report to the usage reporting API
   */
  agentVersion?: string;
  /**
   * Client name to report to the usage reporting API
   */
  clientName?: StringFromRequestFn;
  /**
   * Client version to report to the usage reporting API
   */
  clientVersion?: StringFromRequestFn;
  /**
   * The version of the runtime (like 'node v23.7.0')
   * @default empty string.
   */
  runtimeVersion?: string;
  /**
   * The hostname of the machine running this server
   * @default $HOSTNAME environment variable
   */
  hostname?: string;
  /**
   * The OS identification string.
   * The format is `${os.platform()}, ${os.type()}, ${os.release()}, ${os.arch()})`
   * @default empty string
   */
  uname?: string;
  /**
   * The maximum estimated size of each traces in bytes. If the estimated size is higher than this threshold,
   * the complete trace will not be sent and will be reduced to aggregated stats.
   *
   * Note: GraphOS only allow for traces of 10mb maximum
   * @default 10 * 1024 * 1024 (10mb)
   */
  maxTraceSize?: number;
  /**
   * The maximum uncompressed size of a report in bytes.
   * The report will be sent once this threshold is reached, even if the delay between send is not
   * yet expired.
   *
   * @default 4Mb
   */
  maxBatchUncompressedSize?: number;
  /**
   * The maximum time in ms between reports.
   * @default 20s
   */
  maxBatchDelay?: number;
  /**
   * Control if traces should be always sent.
   * If false, the traces will be batched until a delay or size is reached.
   * Note: This is highly not recommended in a production environment
   *
   * @default false
   */
  alwaysSend?: boolean;
  /**
   * Timeout in ms of a trace export tentative
   * @default 30s
   */
  exportTimeout?: number;
  /**
   * The class to be used to keep track of traces and send them to the GraphOS endpoint
   * Note: This option is aimed to be used for testing purposes
   */
  reporter?: (options: ApolloUsageReportOptions, yoga: YogaServer<Record<string, unknown>, Record<string, unknown>>, logger: YogaLogger) => Reporter;
  /**
   * Called when all retry attempts to send a report to GraphOS endpoint failed.
   * By default, the error is logged.
   */
  onError?: (err: Error) => void;
  /**
   * If false, unexecutable operation (with parsing or validation error) will not be sent
   * @default false
   */
  sendUnexecutableOperationDocuments?: boolean;
};
interface ApolloUsageReportRequestContext extends ApolloInlineRequestTraceContext {
  traces: Map<YogaInitialContext, ApolloUsageReportGraphqlContext>;
}
interface ApolloUsageReportGraphqlContext extends ApolloInlineGraphqlTraceContext {
  referencedFieldsByType?: ReturnType<typeof calculateReferencedFieldsByType>;
  operationKey?: string;
  schemaId?: string;
}
type StringFromRequestFn = (req: Request) => Maybe<string>;
declare function useApolloUsageReport(options?: ApolloUsageReportOptions): Plugin;
declare function hashSHA256(text: string, api?: {
  crypto: Crypto;
  TextEncoder: (typeof globalThis)['TextEncoder'];
}): Promise<string>;
//#endregion
export { ApolloUsageReportGraphqlContext, ApolloUsageReportOptions, ApolloUsageReportRequestContext, hashSHA256, useApolloUsageReport };