import { SpanStatus, Attributes, SpanStatusCode } from '@opentelemetry/api';
import { Logger } from './logger.cjs';
export { EventCollector, EventData, EventsFunnelStep, EventsOutcome, EventsValue, assertEventTracked, assertOutcomeTracked, createEventCollector } from './event-testing.cjs';
import 'pino';
import './event-subscriber.cjs';

/**
 * Testing Utilities
 *
 * Helpers for testing instrumented code and verifying telemetry.
 * Perfect for integration tests and QA in production validation.
 *
 * @example Verify traces are created
 * ```typescript
 * import { assertTraceCreated, collectTraces } from '@your-org/otel-decorators/testing'
 *
 * describe('UserService', () => {
 *   it('should create trace for user creation', async () => {
 *     const collector = collectTraces()
 *
 *     const service = new UserService()
 *     await service.createUser({ email: 'test@example.com' })
 *
 *     assertTraceCreated(collector, 'user.createUser')
 *   })
 * })
 * ```
 */

/**
 * Note: OpenTelemetry exporters and processors have moved to dedicated modules
 * for better semantic clarity.
 *
 * For exporters (ConsoleSpanExporter, InMemorySpanExporter):
 * @see {@link autotel/exporters}
 *
 * For processors (SimpleSpanProcessor, BatchSpanProcessor):
 * @see {@link autotel/processors}
 *
 * This module focuses on high-level testing utilities with assertion helpers
 * and trace collectors.
 *
 * @example High-level testing (recommended)
 * ```typescript
 * import { createTraceCollector, assertTraceCreated } from 'autotel/testing'
 *
 * const collector = createTraceCollector()
 * await myService.doSomething()
 * assertTraceCreated(collector, 'myService.doSomething')
 * ```
 *
 * @example Low-level testing (when you need raw OTel spans)
 * ```typescript
 * import { InMemorySpanExporter } from 'autotel/exporters'
 * import { SimpleSpanProcessor } from 'autotel/processors'
 *
 * const exporter = new InMemorySpanExporter()
 * init({ service: 'test', spanProcessor: new SimpleSpanProcessor(exporter) })
 * ```
 */
/**
 * Simplified span representation for testing
 */
interface TestSpan {
    name: string;
    status: SpanStatus;
    attributes: Attributes;
    startTime: number;
    endTime: number;
    duration: number;
}
/**
 * In-memory trace collector for testing
 */
interface TraceCollector {
    /** Get all collected spans */
    getSpans(): TestSpan[];
    /** Get spans matching a name */
    getSpansByName(name: string): TestSpan[];
    /** Get spans matching attributes */
    getSpansByAttributes(attributes: Record<string, unknown>): TestSpan[];
    /** Clear all collected spans */
    clear(): void;
    /** Record a span (internal use) */
    recordSpan(span: TestSpan): void;
}
/**
 * Create an in-memory trace collector for testing
 *
 * IMPORTANT: This automatically configures the global tracer to record spans.
 * Call this in your test's beforeEach() to ensure proper setup.
 *
 * @example
 * ```typescript
 * import { createTraceCollector } from 'autotel/testing'
 *
 * describe('MyService', () => {
 *   let collector: TraceCollector
 *
 *   beforeEach(() => {
 *     collector = createTraceCollector()
 *   })
 *
 *   it('should trace operations', async () => {
 *     await myService.doSomething()
 *
 *     const spans = collector.getSpansByName('myService.doSomething')
 *     expect(spans).toHaveLength(1)
 *   })
 * })
 * ```
 */
declare function createTraceCollector(): TraceCollector;
/**
 * Assert that a trace was created for an operation
 *
 * @param collector - Trace collector
 * @param operationName - Expected operation name
 * @param options - Optional assertion options
 * @throws Error if trace was not found or doesn't match expectations
 *
 * @example
 * ```typescript
 * assertTraceCreated(collector, 'user.createUser')
 * assertTraceCreated(collector, 'user.createUser', {
 *   minCount: 1,
 *   maxCount: 1,
 *   status: SpanStatusCode.OK,
 *   attributes: { 'user.email': 'test@example.com' }
 * })
 * ```
 */
declare function assertTraceCreated(collector: TraceCollector, operationName: string, options?: {
    minCount?: number;
    maxCount?: number;
    status?: SpanStatusCode;
    attributes?: Record<string, unknown>;
}): void;
/**
 * Assert that no errors were logged
 *
 * Use this in smoke tests to verify critical paths don't have errors.
 *
 * @param collector - Trace collector
 * @throws Error if any error traces are found
 *
 * @example
 * ```typescript
 * // Run critical user flows
 * await runSmokeTests()
 *
 * // Verify no errors occurred
 * assertNoErrors(collector)
 * ```
 */
declare function assertNoErrors(collector: TraceCollector): void;
/**
 * Assert that a trace was created and succeeded
 *
 * @param collector - Trace collector
 * @param operationName - Expected operation name
 *
 * @example
 * ```typescript
 * assertTraceSucceeded(collector, 'user.createUser')
 * ```
 */
declare function assertTraceSucceeded(collector: TraceCollector, operationName: string): void;
/**
 * Assert that a trace was created and failed
 *
 * @param collector - Trace collector
 * @param operationName - Expected operation name
 * @param errorMessage - Optional expected error message
 *
 * @example
 * ```typescript
 * assertTraceFailed(collector, 'user.createUser', 'Invalid email')
 * ```
 */
declare function assertTraceFailed(collector: TraceCollector, operationName: string, errorMessage?: string): void;
/**
 * In-memory log collector for testing
 */
interface LogCollector {
    /** Get all collected logs */
    getLogs(): LogEntry[];
    /** Get logs by level */
    getLogsByLevel(level: 'info' | 'warn' | 'error' | 'debug'): LogEntry[];
    /** Get logs containing a message */
    getLogsByMessage(message: string): LogEntry[];
    /** Clear all collected logs */
    clear(): void;
}
/**
 * Log entry
 */
interface LogEntry {
    level: 'info' | 'warn' | 'error' | 'debug';
    message: string;
    extra?: Record<string, unknown>;
    error?: Error;
}
/**
 * Create an in-memory log collector for testing
 *
 * @example
 * ```typescript
 * const logger = createMockLogger()
 *
 * // Use logger in your code
 * service.log = logger
 * await service.doSomething()
 *
 * // Assert logs were created
 * const logs = logger.getLogs()
 * expect(logs).toHaveLength(2)
 * expect(logs[0].message).toBe('Operation started')
 * ```
 */
declare function createMockLogger(): Logger & LogCollector;
/**
 * Assert that no error logs were created
 *
 * @param logger - Log collector
 * @throws Error if any error logs are found
 *
 * @example
 * ```typescript
 * assertNoErrorsLogged(logger)
 * ```
 */
declare function assertNoErrorsLogged(logger: LogCollector): void;
/**
 * Wait for a specific trace to be created
 *
 * Useful for async operations where you need to wait for telemetry.
 *
 * @param collector - Trace collector
 * @param operationName - Expected operation name
 * @param timeoutMs - Timeout in milliseconds (default 5000)
 * @returns Promise that resolves when trace is found
 * @throws Error if timeout is reached
 *
 * @example
 * ```typescript
 * // Start async operation
 * const promise = service.doAsyncWork()
 *
 * // Wait for trace
 * await waitForTrace(collector, 'service.doAsyncWork', 1000)
 *
 * // Now you can assert on the trace
 * assertTraceSucceeded(collector, 'service.doAsyncWork')
 * ```
 */
declare function waitForTrace(collector: TraceCollector, operationName: string, timeoutMs?: number): Promise<void>;
/**
 * Get trace duration in milliseconds
 *
 * @param collector - Trace collector
 * @param operationName - Operation name
 * @returns Duration in milliseconds, or undefined if trace not found
 *
 * @example
 * ```typescript
 * const duration = getTraceDuration(collector, 'user.createUser')
 * expect(duration).toBeLessThan(1000) // Should be < 1s
 * ```
 */
declare function getTraceDuration(collector: TraceCollector, operationName: string): number | undefined;
/**
 * Assert that an operation completed within a time threshold
 *
 * Perfect for performance testing and SLO validation.
 *
 * @param collector - Trace collector
 * @param operationName - Operation name
 * @param maxDurationMs - Maximum allowed duration in milliseconds
 * @throws Error if operation took too long
 *
 * @example
 * ```typescript
 * // Verify operation meets SLO
 * await service.createUser({ email: 'test@example.com' })
 * assertTraceDuration(collector, 'user.createUser', 500) // Must be < 500ms
 * ```
 */
declare function assertTraceDuration(collector: TraceCollector, operationName: string, maxDurationMs: number): void;

export { type LogCollector, type LogEntry, type TestSpan, type TraceCollector, assertNoErrors, assertNoErrorsLogged, assertTraceCreated, assertTraceDuration, assertTraceFailed, assertTraceSucceeded, createMockLogger, createTraceCollector, getTraceDuration, waitForTrace };
