import { context } from '@opentelemetry/api';

/**
 * HTTP Instrumentation Helpers
 *
 * Optional import: Not included in main bundle
 * Import from: 'autotel/http'
 *
 * Provides decorators and utilities for HTTP client instrumentation.
 * Works with fetch, axios, and other HTTP clients.
 *
 * @example
 * ```typescript
 * import { HttpInstrumented } from 'autotel/http'
 *
 * @HttpInstrumented()
 * class ApiClient {
 *   async getUser(id: string) {
 *     return fetch(`/api/users/${id}`)
 *   }
 * }
 * ```
 */

interface HttpInstrumentedOptions {
    /** Service name for HTTP calls (default: 'http-client') */
    serviceName?: string;
    /** Extract URL from method arguments (default: first arg) */
    urlExtractor?: (args: unknown[]) => string | undefined;
    /** Extract HTTP method from method name or args */
    methodExtractor?: (methodName: string, args: unknown[]) => string;
    /** Add custom attributes to spans */
    attributesFromArgs?: (args: unknown[]) => Record<string, string | number>;
    /** Slow request threshold in milliseconds (adds warning attribute) - default: 3000ms */
    slowRequestThresholdMs?: number;
}
/**
 * Decorator for auto-instrumenting HTTP client methods
 *
 * @example Basic usage
 * ```typescript
 * @HttpInstrumented()
 * class ApiClient {
 *   async fetchUser(userId: string) {
 *     const res = await fetch(`https://api.example.com/users/${userId}`)
 *     return res.json()
 *   }
 *
 *   async createOrder(order: Order) {
 *     const res = await fetch('https://api.example.com/orders', {
 *       method: 'POST',
 *       body: JSON.stringify(order)
 *     })
 *     return res.json()
 *   }
 * }
 * ```
 *
 * @example Advanced usage with custom extractors
 * ```typescript
 * @HttpInstrumented({
 *   serviceName: 'payment-gateway',
 *   urlExtractor: (args) => {
 *     const config = args[0] as RequestConfig
 *     return config.url
 *   },
 *   attributesFromArgs: (args) => ({
 *     'http.request_id': args[0]?.requestId,
 *     'http.retry_count': args[0]?.retryCount || 0
 *   })
 * })
 * class PaymentClient {
 *   async charge(config: RequestConfig) {
 *     return axios(config)
 *   }
 * }
 * ```
 */
declare function HttpInstrumented(options?: HttpInstrumentedOptions): <T extends {
    new (...args: any[]): {};
}>(target: T, _context: ClassDecoratorContext) => {
    new (...args: any[]): {};
} & T;
/**
 * Helper: Trace a single HTTP request
 *
 * @example
 * ```typescript
 * import { traceHttpRequest } from 'autotel/http'
 *
 * const data = await traceHttpRequest(
 *   'GET /api/users',
 *   () => fetch('https://api.example.com/users')
 * )
 * ```
 */
declare function traceHttpRequest<T>(spanName: string, fn: () => Promise<T>, attributes?: Record<string, string | number>): Promise<T>;
/**
 * Inject trace context into HTTP headers (for distributed tracing)
 *
 * This includes W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.
 * Uses OpenTelemetry's propagation system for full compatibility.
 *
 * @example
 * ```typescript
 * import { injectTraceContext } from 'autotel/http'
 *
 * const headers = injectTraceContext({
 *   'Content-Type': 'application/json'
 * })
 *
 * fetch('/api/users', { headers })
 * ```
 *
 * @example With baggage
 * ```typescript
 * import { trace, withBaggage, injectTraceContext } from 'autotel'
 *
 * export const createOrder = trace((ctx) => async (order: Order) => {
 *   return await withBaggage({
 *     baggage: { 'tenant.id': order.tenantId },
 *     fn: async () => {
 *       const headers = injectTraceContext();
 *       // Headers now include 'baggage' header with tenant.id
 *       await fetch('/api/charge', { headers });
 *     },
 *   });
 * });
 * ```
 */
declare function injectTraceContext(headers?: Record<string, string>): Record<string, string>;
/**
 * Extract trace context from HTTP headers (for distributed tracing)
 *
 * This extracts W3C Trace Context (traceparent, tracestate) and W3C Baggage headers.
 * Uses OpenTelemetry's propagation system for full compatibility.
 *
 * Returns a context that can be used with context.with() to run code
 * with the extracted trace context and baggage.
 *
 * @example
 * ```typescript
 * import { extractTraceContext, trace } from 'autotel'
 * import { context } from 'autotel'
 *
 * // In Express middleware
 * app.use((req, res, next) => {
 *   const extractedContext = extractTraceContext(req.headers);
 *   context.with(extractedContext, () => {
 *     next();
 *   });
 * });
 * ```
 *
 * @example In a traced function
 * ```typescript
 * export const handleWebhook = trace((ctx) => async (req: Request) => {
 *   const extractedContext = extractTraceContext(req.headers);
 *   return await context.with(extractedContext, async () => {
 *     // Now ctx.getBaggage() will return baggage from the incoming request
 *     const tenantId = ctx.getBaggage('tenant.id');
 *     await processWebhook(req.body);
 *   });
 * });
 * ```
 */
declare function extractTraceContext(headers: Record<string, string | string[] | undefined>): ReturnType<typeof context.active>;

export { HttpInstrumented, type HttpInstrumentedOptions, extractTraceContext, injectTraceContext, traceHttpRequest };
