import { z } from 'zod';

/**
 * Zod schema for a single request configuration.
 */
declare const RequestConfigSchema: z.ZodObject<{
    /** The URL to send the request to. */
    url: z.ZodString;
    /** The request payload. Can be a JSON object or an array. */
    payload: z.ZodOptional<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodUnknown, "many">]>>;
    /** The HTTP method to use for the request. Defaults to GET. */
    method: z.ZodDefault<z.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]>, "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS", unknown>>;
    /** Headers to be sent with this specific request. Merged with global headers. */
    headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
}, "strip", z.ZodTypeAny, {
    url: string;
    method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
    headers?: Record<string, string> | undefined;
    payload?: unknown[] | Record<string, unknown> | undefined;
}, {
    url: string;
    headers?: Record<string, string> | undefined;
    payload?: unknown[] | Record<string, unknown> | undefined;
    method?: unknown;
}>;
/**
 * Zod schema for the main Tressi configuration.
 */
declare const TressiConfigSchema: z.ZodObject<{
    /** A URL to the JSON schema for this configuration file. */
    $schema: z.ZodOptional<z.ZodString>;
    /** Global headers to be sent with every request. */
    headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
    /** An array of request configurations. */
    requests: z.ZodArray<z.ZodObject<{
        /** The URL to send the request to. */
        url: z.ZodString;
        /** The request payload. Can be a JSON object or an array. */
        payload: z.ZodOptional<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodUnknown, "many">]>>;
        /** The HTTP method to use for the request. Defaults to GET. */
        method: z.ZodDefault<z.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]>, "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS", unknown>>;
        /** Headers to be sent with this specific request. Merged with global headers. */
        headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
    }, "strip", z.ZodTypeAny, {
        url: string;
        method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
        headers?: Record<string, string> | undefined;
        payload?: unknown[] | Record<string, unknown> | undefined;
    }, {
        url: string;
        headers?: Record<string, string> | undefined;
        payload?: unknown[] | Record<string, unknown> | undefined;
        method?: unknown;
    }>, "many">;
}, "strip", z.ZodTypeAny, {
    requests: {
        url: string;
        method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
        headers?: Record<string, string> | undefined;
        payload?: unknown[] | Record<string, unknown> | undefined;
    }[];
    $schema?: string | undefined;
    headers?: Record<string, string> | undefined;
}, {
    requests: {
        url: string;
        headers?: Record<string, string> | undefined;
        payload?: unknown[] | Record<string, unknown> | undefined;
        method?: unknown;
    }[];
    $schema?: string | undefined;
    headers?: Record<string, string> | undefined;
}>;
/**
 * Type representing the Tressi configuration.
 */
type TressiConfig = z.infer<typeof TressiConfigSchema>;
/**
 * Type representing a single request configuration.
 */
type RequestConfig = z.infer<typeof RequestConfigSchema>;

interface EndpointSummary {
    method: string;
    url: string;
    totalRequests: number;
    successfulRequests: number;
    failedRequests: number;
    avgLatencyMs: number;
    minLatencyMs: number;
    maxLatencyMs: number;
    p95LatencyMs: number;
    p99LatencyMs: number;
}
interface GlobalSummary {
    totalRequests: number;
    successfulRequests: number;
    failedRequests: number;
    avgLatencyMs: number;
    minLatencyMs: number;
    maxLatencyMs: number;
    p95LatencyMs: number;
    p99LatencyMs: number;
    actualRps: number;
    theoreticalMaxRps: number;
    achievedPercentage: number;
    duration: number;
}
interface TestSummary {
    tressiVersion: string;
    global: GlobalSummary;
    endpoints: EndpointSummary[];
}

/**
 * Defines the options for a Tressi load test run.
 */
interface RunOptions {
    /** The configuration for the test. Can be a path to a file, a URL, or a configuration object. */
    config: string | TressiConfig;
    /** The number of concurrent workers to use. Defaults to 10. For autoscale, this is the max workers. */
    workers?: number;
    /** The total duration of the test in seconds. Defaults to 10. */
    durationSec?: number;
    /** The time in seconds to ramp up to the target RPS. Defaults to 0. */
    rampUpTimeSec?: number;
    /** The target requests per second. If not provided, the test will run at maximum possible speed. */
    rps?: number;
    /** Whether to enable autoscale mode. Defaults to false. --rps is required for this. */
    autoscale?: boolean;
    /** The base path for the exported report. If not provided, no report will be generated. */
    exportPath?: string | boolean;
    /** Whether to use the terminal UI. Defaults to true. */
    useUI?: boolean;
    /** Suppress all console output. Defaults to false. */
    silent?: boolean;
    /** Whether to enable early exit on error conditions. Defaults to false. */
    earlyExitOnError?: boolean;
    /** Error rate threshold (0.0-1.0) to trigger early exit. Requires earlyExitOnError=true. */
    errorRateThreshold?: number;
    /** Absolute error count threshold to trigger early exit. Requires earlyExitOnError=true. */
    errorCountThreshold?: number;
    /** Specific HTTP status codes that should trigger early exit. Requires earlyExitOnError=true. */
    errorStatusCodes?: number[];
    /** Number of concurrent requests per worker. Defaults to dynamic calculation based on target RPS. */
    concurrentRequestsPerWorker?: number;
}
/**
 * The main function to execute a Tressi load test.
 * It loads the configuration, initializes the runner, starts the UI,
 * and prints a summary upon completion.
 * @param options The `RunOptions` for the test.
 * @returns A `Promise` that resolves with the `TestSummary` object.
 */
declare function runLoadTest(options: RunOptions): Promise<TestSummary>;

export { type RequestConfig, type RunOptions, type TestSummary, type TressiConfig, runLoadTest };
