import { A as AppiumReporterConfig, R as ResolvedAppiumConfig, P as Platform, a as AppTestMode, D as DetectedCapabilities, b as AppiumCommandStep, c as AppiumAssertionStep, C as CollectedTestData, d as DeviceLogEntry, e as AppiumNetworkEntry } from './service-CebBtv5u.js';
export { f as CommandCategory, g as DeviceLogSource, T as TestRelicService } from './service-CebBtv5u.js';
import WdioReporter, { RunnerStats, SuiteStats, TestStats } from '@wdio/reporter';
import { TestStatus, ConsoleLogEntry, CapturedNetworkRequest, TimelineEntry, CloudConfig, AuthMode, GitMetadata, Summary, TimelineStep, TestRunReport, CIMetadata, ActionStep, CloudReporterOptions } from '@testrelic/core';
export { ActionCategory, ActionStep, ArtifactRunManifest, AuthMode, AuthState, CIMetadata, CIProvider, CloudConfig, CloudReporterOptions, ConsoleLogEntry, ConsoleLogLevel, FailureDiagnostic, GitMetadata, MergeOptions, QueueEntry, ReportMode, StreamingReportSummary, Summary, TestArtifacts, TestDetailData, TestIndexEntry, TestResult, TestRunReport, TestStatus, TimelineEntry, TimelineStep, UploadStrategy } from '@testrelic/core';
export { mergeReports } from './merge.js';

/**
 * Config resolution with prototype pollution prevention.
 * Merges user options into defaults and freezes the result.
 */

declare function resolveConfig(options?: Partial<AppiumReporterConfig>): ResolvedAppiumConfig;

/**
 * Auto-detect test mode and platform from W3C capabilities.
 *
 * Inspects `platformName`, `appium:app`, and `browserName` to determine
 * whether the session targets a native app, hybrid app, or mobile web.
 */

declare function detectTestMode(caps: Record<string, unknown>): AppTestMode;
declare function detectPlatform(caps: Record<string, unknown>): Platform;
declare function extractCapabilities(caps: Record<string, unknown>): DetectedCapabilities;

declare function createRedactor(patterns: (string | RegExp)[]): (text: string) => string;
declare function shouldRedactCommand(commandName: string): boolean;
declare function redactArgs(args: unknown[], commandName: string): unknown[];

/**
 * JSONL (JSON Lines) streaming writer and reader.
 *
 * Writer: Appends one JSON object per line to a file using a persistent fd.
 * Reader: Reads a specific page of lines from a JSONL file without loading
 *         the entire file into memory.
 */
declare class JsonlFileWriter {
    private readonly filePath;
    private readonly fd;
    private count;
    private closed;
    constructor(prefix: string);
    append(obj: unknown): void;
    getPath(): string;
    getCount(): number;
    close(): void;
    cleanup(): void;
}
declare function readJsonlPage<T>(filePath: string, page: number, pageSize: number, knownTotal?: number): Promise<{
    items: T[];
    total: number;
    page: number;
    pageSize: number;
    totalPages: number;
}>;

/**
 * Builds TimelineEntry arrays from captured Appium test data.
 * Maps mobile test data to the @testrelic/core TimelineEntry shape.
 */

interface TimelineBuildInput {
    readonly testTitle: string;
    readonly suiteName: string;
    readonly filePath: string;
    readonly status: TestStatus;
    readonly duration: number;
    readonly startedAt: string;
    readonly completedAt: string;
    readonly error: string | null;
    readonly stack: string | null;
    readonly retryCount: number;
    readonly commands: AppiumCommandStep[];
    readonly assertions: AppiumAssertionStep[];
    readonly consoleLogs: ConsoleLogEntry[];
    readonly networkRequests: CapturedNetworkRequest[];
    readonly screenshotPaths: string[];
    readonly videoPath: string | null;
    readonly capabilities: DetectedCapabilities;
}
declare function buildTimelineEntry(input: TimelineBuildInput): TimelineEntry;
declare function buildTimeline(inputs: TimelineBuildInput[]): TimelineEntry[];

/**
 * CloudClient — manages cloud connectivity lifecycle.
 *
 * Handles auth, mode transitions, repo resolution, token refresh,
 * and queue flush orchestration. Never throws — all errors result
 * in graceful local-mode fallback.
 */

declare class CloudClient {
    private config;
    private authState;
    private gitMetadata;
    private repoId;
    private failureReason;
    private flushPromise;
    private healthCheckTimer;
    constructor(cloudConfig: CloudConfig | null);
    initialize(): Promise<void>;
    getMode(): AuthMode;
    isCloudMode(): boolean;
    isLocalMode(): boolean;
    getAccessToken(): string | null;
    getRepoId(): string | null;
    getGitMetadata(): GitMetadata | null;
    getConfig(): CloudConfig | null;
    getFailureReason(): string | null;
    getEndpoint(): string;
    ensureValidToken(): Promise<boolean>;
    switchToLocalMode(reason: string): void;
    dispose(): Promise<void>;
    private setLocalMode;
    private handleAuthError;
    private resolveRepoId;
    private readRepoCache;
    private writeRepoCache;
    private hashApiKey;
    private startBackgroundFlush;
    private startHealthCheck;
}

/**
 * Cloud upload — batch and realtime upload functions.
 *
 * Handles payload construction, gzip compression for large payloads,
 * retry with exponential backoff, rate limit handling, and structured
 * failure reporting.
 */

interface TestResultForUpload {
    readonly testId: string;
    readonly title: string;
    readonly status: string;
    readonly duration: number;
    readonly suiteName: string;
    readonly filePath: string;
    readonly testType: string;
    readonly isFlaky: boolean;
    readonly startedAt: string;
    readonly completedAt: string;
    readonly tags: readonly string[];
    readonly failure: unknown | null;
    readonly retry: number;
    readonly retryCount: number;
    readonly retryStatus: string | null;
    readonly source?: string;
    readonly browser?: string;
    readonly os?: string;
    readonly runner?: string;
    readonly resolution?: string;
    readonly platform?: string;
    readonly deviceName?: string;
    readonly appTestMode?: string;
}
interface RunUploadPayload {
    readonly runId: string;
    readonly repoGitId: string;
    readonly startedAt: string;
    readonly summary: Summary;
    readonly timeline: readonly (TimelineEntry | TimelineStep)[];
    readonly tests?: readonly TestResultForUpload[];
    readonly branch?: string;
    readonly commit?: string;
    readonly commitMessage?: string;
    readonly commitAuthor?: string;
    readonly finishedAt?: string;
    readonly duration?: number;
    readonly ciProvider?: string;
    readonly ciRunUrl?: string;
    readonly environment?: string;
    readonly testFramework?: string;
    /** Run-level test type — always 'mobile' for Appium runs. */
    readonly testType?: string;
}
interface UploadResult {
    readonly success: boolean;
    readonly statusCode: number | null;
    readonly error: string | null;
}
interface UploadFailure {
    readonly success: false;
    readonly reason: string;
    readonly statusCode: number | null;
    readonly payload: Record<string, unknown>;
    readonly targetEndpoint: string;
    readonly method: string;
}
declare function buildUploadPayload(report: TestRunReport, repoGitId: string, git: GitMetadata | null, ci: CIMetadata | null, tests?: readonly TestResultForUpload[]): RunUploadPayload;
declare function uploadBatchRun(endpoint: string, accessToken: string, payload: RunUploadPayload, onTokenRefresh?: () => Promise<string | null>): Promise<UploadResult | UploadFailure>;
interface RealtimeInitResult {
    readonly runId: string;
}
declare function initRealtimeRun(endpoint: string, accessToken: string, payload: {
    runId: string;
    repoGitId: string;
    branch: string | null;
    commit: string | null;
    commitMessage?: string | null;
    commitAuthor?: string | null;
    startedAt: string;
    totalTests: number | null;
    ciProvider: string | null;
    ciRunUrl: string | null;
    environment?: string | null;
    testFramework?: string;
    testType?: string;
}): Promise<RealtimeInitResult | null>;
declare function uploadTestResult(endpoint: string, accessToken: string, cloudRunId: string, testData: Record<string, unknown>): void;
declare function finalizeRun(endpoint: string, accessToken: string, cloudRunId: string, payload: {
    finishedAt: string;
    duration: number;
    summary: Summary;
    commitMessage?: string | null;
    testType?: string;
}): Promise<boolean>;
declare function finalizeRunFireAndForget(endpoint: string, accessToken: string, cloudRunId: string, startedAt: string): void;

/**
 * Cloud reporter orchestration — init, upload, and finalize cloud runs.
 *
 * Mirrors the Playwright cloud-reporter.ts flow, adapted for Appium's
 * data shapes (commands, device logs, capabilities). Never throws —
 * all errors result in graceful degradation.
 */

/**
 * Initialize a realtime run on the cloud during onRunnerStart.
 * Returns the cloud run ID, or null if init fails or is not applicable.
 */
declare function initCloudRun(cloudClient: CloudClient, uploadStrategy: string | undefined, testRunId: string, startedAt: string, environment?: string): Promise<string | null>;
declare function buildCloudTestPayload(input: TimelineBuildInput, testId: string): Record<string, unknown>;
interface ArtifactEntry {
    readonly testId: string;
    readonly screenshotPaths: readonly string[];
    readonly videoPath: string | null;
    readonly consoleLogs: readonly ConsoleLogEntry[];
    readonly networkRequests: readonly CapturedNetworkRequest[];
}
/**
 * Finalize realtime run, perform batch upload, and dispose the cloud client.
 * Queues failed uploads for later retry. Never throws.
 */
declare function finalizeAndUpload(cloudClient: CloudClient, cloudConfig: CloudConfig | undefined | null, uploadStrategy: string | undefined, testRunId: string, cloudRunId: string | null, report: TestRunReport, completedAt: string, totalDuration: number, summary: Summary, artifactEntries?: readonly ArtifactEntry[], tests?: readonly TestResultForUpload[]): Promise<void>;

/**
 * WDIO Reporter: Receives test lifecycle events, aggregates captured data,
 * builds timelines, computes summaries, and produces output files.
 *
 * Extends the official @wdio/reporter base class so WDIO can correctly
 * call emit() and isSynchronised during shutdown.
 *
 * Cloud lifecycle: CloudClient init in onRunnerStart, per-test realtime
 * upload in onTestEnd, finalizeAndUpload in onRunnerEnd.
 */

interface ServiceRef {
    getCollectedData(): {
        commands: CollectedTestData['commands'];
        assertions: CollectedTestData['assertions'];
        deviceLogs?: CollectedTestData['deviceLogs'];
        networkEntries?: CollectedTestData['networkEntries'];
        screenshotPaths?: CollectedTestData['screenshotPaths'];
        videoPath?: CollectedTestData['videoPath'];
        detectedCaps?: CollectedTestData['detectedCaps'];
        [key: string]: unknown;
    };
}
declare class TestRelicReporter extends WdioReporter {
    /** Prefix for per-worker manifest files (one file per worker, named by testRunId) */
    static FINALIZE_MANIFEST_PREFIX: string;
    static FINALIZE_MANIFEST_SUFFIX: string;
    /** @deprecated use FINALIZE_MANIFEST_PREFIX — kept for backward compatibility */
    static FINALIZE_MANIFEST_FILENAME: string;
    static pendingFinalize: (() => Promise<void>) | null;
    private appiumConfig;
    private inputs;
    private startedAt;
    private testRunId;
    private cloudClient;
    private cloudRunId;
    private cloudInitPromise;
    private artifactEntries;
    private signalHandlersRegistered;
    private _serviceRef;
    private _uploadDone;
    /** True while the cross-process manifest write is in flight; blocks isSynchronised. */
    private _manifestPending;
    /**
     * Call from the WDIO `onComplete` config hook to await the cloud upload.
     * Because `onComplete` is awaited by WDIO before process.exit(), this
     * correctly blocks shutdown until the upload is fully done.
     *
     * WDIO runs reporters in a worker process and onComplete in the main process.
     * Each worker writes a uniquely-named manifest; this method discovers and
     * processes all of them so parallel workers each get their own upload.
     */
    static finalize(manifestDir?: string): Promise<void>;
    constructor(options: Partial<AppiumReporterConfig>);
    onRunnerStart(_runner: RunnerStats): void;
    private initCloud;
    private registerSignalHandlers;
    get isSynchronised(): boolean;
    setServiceRef(ref: ServiceRef): void;
    onSuiteStart(_suite: SuiteStats): void;
    onTestEnd(test: TestStats): void;
    onRunnerEnd(_runner?: RunnerStats): TestRunReport;
    private writeReport;
    getTimeline(): TimelineEntry[];
    getInputs(): TimelineBuildInput[];
}

/**
 * Formatted console summary output for Appium test runs.
 * Prints a box-drawing formatted summary to stderr at test run completion.
 */

declare function printConsoleSummary(summary: Summary, outputPath: string, htmlReportPath: string, quiet: boolean, deviceLogCount?: number): void;

/**
 * Generate and write the HTML report file.
 *
 * Thin wrapper: serialises TestRunReport to JSON and delegates to
 * renderHtmlDocument() from html-template.ts — same pattern as Playwright.
 */

declare function generateHtmlReport(report: TestRunReport, outputPath: string): void;

/**
 * Cross-platform browser auto-open utility.
 * Fire-and-forget — never throws, errors logged to stderr.
 */
declare function openInBrowser(filePath: string): void;

/**
 * ReportServer — HTTP server for serving streaming reports and artifacts.
 * Binds to 127.0.0.1 only. Auto-selects port starting at 9323.
 */
interface ReportServerHandle {
    port: number;
    dispose: () => Promise<void>;
}
declare function startReportServer(reportDir: string, options?: {
    port?: number;
}): Promise<ReportServerHandle>;

/**
 * StreamingWriter — writes test data to disk incrementally.
 * Each test gets a directory with meta.json and optional JSONL data files.
 */
declare function generateStreamingTestId(filePath: string, titlePath: readonly string[], project: string, retryIndex: number): string;
declare class StreamingWriter {
    private readonly reportDir;
    private readonly testsDir;
    private totalBytesWritten;
    constructor(outputDir: string);
    getReportDir(): string;
    writeTestDetail(testId: string, data: Record<string, unknown>, files?: {
        deviceLogsFile?: string | null;
        consoleLogsFile?: string | null;
        networkLogsFile?: string | null;
    }): boolean;
    private moveFile;
    writeIndex(entries: unknown[]): void;
    writeSummary(summary: unknown): void;
    computeTotalSize(): number;
    dispose(): void;
}

/**
 * ArtifactManager — copies screenshots and videos to structured output folders.
 */
declare function sanitizeFolderName(title: string): string;
interface CopiedArtifacts {
    readonly screenshot?: string;
    readonly video?: string;
}
declare function copyArtifacts(screenshotPaths: string[], videoPath: string | null, testTitle: string, outputDir: string): CopiedArtifacts | null;

/**
 * Computes Summary stats from TimelineEntry arrays.
 */

declare function buildSummary(timeline: readonly TimelineEntry[]): Summary;

/**
 * Normalizes captured service data into reporter-consumable shapes.
 * Maps Appium command steps and assertion steps to core ActionStep format.
 */

declare function commandStepToAction(step: AppiumCommandStep): ActionStep;
declare function assertionStepToAction(step: AppiumAssertionStep): ActionStep;
declare function deviceLogToConsoleEntry(entry: DeviceLogEntry): ConsoleLogEntry;
declare function networkEntryToRequest(entry: AppiumNetworkEntry): CapturedNetworkRequest;

/**
 * Cloud authentication — token exchange and refresh.
 *
 * Handles the JWT exchange model: API key → short-lived access token.
 * All HTTP via built-in `fetch` (Node.js 18+). Timeouts via AbortController.
 *
 * SECURITY: API key is never logged or serialized beyond the single POST body.
 * HTTPS enforced for all non-localhost communication.
 */
interface TokenExchangeResult {
    readonly accessToken: string;
    readonly refreshToken: string;
    readonly expiresIn: number;
    readonly orgId: string;
    readonly orgName: string;
    readonly userId: string;
    readonly userName: string;
}
interface TokenRefreshResult {
    readonly accessToken: string;
    readonly refreshToken: string;
    readonly expiresIn: number;
}
interface AuthError {
    readonly code: 'invalid_key' | 'expired_key' | 'validation_error' | 'rate_limited' | 'server_error' | 'network_error' | 'timeout';
    readonly message: string;
    readonly statusCode: number | null;
}
declare function enforceHttps(endpoint: string): void;
declare function healthCheck(endpoint: string): Promise<boolean>;
declare function exchangeToken(endpoint: string, apiKey: string, timeout: number): Promise<TokenExchangeResult | AuthError>;
declare function isAuthError(result: TokenExchangeResult | AuthError): result is AuthError;
declare function refreshAccessToken(endpoint: string, currentRefreshToken: string, timeout: number): Promise<TokenRefreshResult | null>;
interface RepoResolveResult {
    readonly repoId: string;
    readonly displayName: string;
}
declare function resolveRepo(endpoint: string, accessToken: string, gitId: string, displayName: string, timeout: number, branch?: string | null): Promise<RepoResolveResult | null>;

/**
 * Cloud configuration discovery, parsing, and merging.
 *
 * Discovers `.testrelic/testrelic-config.json` config files, resolves environment variable
 * references, and merges configuration from multiple sources.
 *
 * Priority order (highest wins):
 *   1. Environment variables (TESTRELIC_API_KEY, TESTRELIC_CLOUD_ENDPOINT, etc.)
 *   2. Reporter options in wdio.conf.ts
 *   3. .testrelic/testrelic-config.json config file
 *   4. Built-in defaults
 */

declare const DEFAULT_CLOUD_CONFIG: CloudConfig;
declare function discoverConfigFile(startDir: string): string | null;
declare function parseConfigFile(filePath: string): Record<string, unknown> | null;
declare function resolveEnvVar(value: string): string | null;
declare function resolveEnvVars(obj: Record<string, unknown>): Record<string, unknown>;
declare function parseDuration(value: string): number | null;
declare function mergeCloudConfig(fileConfig: Record<string, unknown> | null, reporterOptions: CloudReporterOptions | undefined): CloudConfig;

/**
 * Git metadata collection and project ID normalization.
 *
 * Collects branch, commit, message, and remote URL using git CLI.
 * Each field fails independently — a missing remote doesn't prevent
 * branch detection.
 */

declare function collectGitMetadata(cwd?: string): GitMetadata;
declare function normalizeGitRemoteUrl(url: string): string;
declare function deriveRepoDisplayName(normalizedUrl: string): string;
declare function readPackageJsonName(dirPath: string): string | null;
declare function deriveNonGitProjectId(dirPath: string): string;

/**
 * CI provider auto-detection via environment variables.
 * Strategy pattern: check providers in priority order, first match wins.
 */

declare function detectCI(env?: Record<string, string | undefined>): CIMetadata | null;

/**
 * Cloud queue — offline storage and retry for failed uploads.
 *
 * Writes failed upload payloads to individual JSON files in .testrelic/queue/.
 * Flushes queued files on next successful auth, oldest first (FIFO).
 * Atomic writes (tmp → rename) prevent corruption.
 */
declare function writeToQueue(queueDirectory: string, runId: string, type: string, reason: string, targetEndpoint: string, method: string, payload: Record<string, unknown>, headers: Record<string, string>): void;
declare function flushQueue(queueDirectory: string, endpoint: string, accessToken: string): Promise<void>;
declare function cleanupExpiredQueue(queueDirectory: string, maxAge: number): void;

/**
 * Cloud artifact upload — binary file upload via presigned S3 URLs.
 *
 * Flow per artifact:
 *   1. POST /artifacts/upload-url → receive presigned PUT URL + artifactId
 *   2. PUT binary file to the presigned URL
 *   3. POST /artifacts/confirm → mark upload complete
 */
interface ArtifactUploadRequest {
    readonly filePath: string;
    readonly runId: string;
    readonly testId: string;
    readonly type: 'screenshot' | 'video' | 'trace' | 'other';
}
interface ArtifactUploadResult {
    readonly success: boolean;
    readonly storageKey: string | null;
    readonly artifactId: string | null;
    readonly error: string | null;
}
declare function uploadArtifact(endpoint: string, accessToken: string, request: ArtifactUploadRequest, maxSizeMb: number): Promise<ArtifactUploadResult>;
declare function uploadArtifacts(endpoint: string, accessToken: string, requests: readonly ArtifactUploadRequest[], maxSizeMb: number): Promise<Map<string, ArtifactUploadResult>>;

export { AppTestMode, AppiumAssertionStep, AppiumCommandStep, AppiumNetworkEntry, AppiumReporterConfig, type ArtifactEntry, type ArtifactUploadRequest, type ArtifactUploadResult, type AuthError, CloudClient, CollectedTestData, DEFAULT_CLOUD_CONFIG, DetectedCapabilities, DeviceLogEntry, JsonlFileWriter, Platform, type RealtimeInitResult, type RepoResolveResult, ResolvedAppiumConfig, type RunUploadPayload, StreamingWriter, TestRelicReporter, type TestResultForUpload, type TokenExchangeResult, type TokenRefreshResult, type UploadFailure, type UploadResult, assertionStepToAction, buildCloudTestPayload, buildSummary, buildTimeline, buildTimelineEntry, buildUploadPayload, cleanupExpiredQueue, collectGitMetadata, commandStepToAction, copyArtifacts, createRedactor, deriveNonGitProjectId, deriveRepoDisplayName, detectCI, detectPlatform, detectTestMode, deviceLogToConsoleEntry, discoverConfigFile, enforceHttps, exchangeToken, extractCapabilities, finalizeAndUpload, finalizeRun, finalizeRunFireAndForget, flushQueue, generateHtmlReport, generateStreamingTestId, healthCheck, initCloudRun, initRealtimeRun, isAuthError, mergeCloudConfig, networkEntryToRequest, normalizeGitRemoteUrl, openInBrowser, parseConfigFile, parseDuration, printConsoleSummary, readJsonlPage, readPackageJsonName, redactArgs, refreshAccessToken, resolveConfig, resolveEnvVar, resolveEnvVars, resolveRepo, sanitizeFolderName, shouldRedactCommand, startReportServer, uploadArtifact, uploadArtifacts, uploadBatchRun, uploadTestResult, writeToQueue };
