/**
 * DatadogLogsDestination -- Datadog Logs Intake output adapter.
 *
 * Delivers governance events to the Datadog Logs Intake API v2 using an
 * array-of-log-objects POST. Mirrors the structural pattern of SplunkHecDestination
 * (plain Node HTTPS, no SDK, same retry / DLQ / gzip semantics).
 *
 * Design decisions:
 *   - No Datadog SDK. Plain HTTPS POST via Node built-ins (no supply-chain risk).
 *   - API key is NEVER stored in plaintext. Only a KMS reference (apiKeyRef) is held.
 *     Resolved at send-time via the injected secret resolver.
 *   - Retry semantics mirror splunk-hec.ts and webhook-delivery.ts:
 *     429 (rate-limited) + 408 (timeout) + 5xx = retryable.
 *     4xx other than 429 / 408 = non-retryable, DLQ immediately.
 *     On 429: Retry-After header is honoured if present.
 *   - Gzip compression (built-in zlib) applied by default. Configurable.
 *   - packBinding is mandatory. Empty binding throws UnboundDataError immediately.
 *   - API key is never emitted to any log stream.
 *   - Max 1000 events per request; max 5 MB body size (uncompressed). Chunking
 *     splits oversized batches into multiple requests automatically.
 *
 * Datadog Logs Intake wire format (v2):
 *   POST https://http-intake.logs.datadoghq.com/api/v2/logs
 *   DD-API-KEY: <api-key>
 *   Content-Type: application/json
 *   Content-Encoding: gzip  (when compression enabled)
 *   Body: [{ ddsource, ddtags, service, hostname, message, timestamp }, ...]
 *
 * Supported sites:
 *   us1     -> http-intake.logs.datadoghq.com   (default)
 *   us3     -> http-intake.logs.us3.datadoghq.com
 *   us5     -> http-intake.logs.us5.datadoghq.com
 *   eu1     -> http-intake.logs.datadoghq.eu
 *   us1-fed -> http-intake.logs.ddog-gov.com
 *
 * @connexum/ai-governance
 */
import type { EventPayload } from '../event-bus';
/**
 * Resolves a KMS/secret-manager reference to the actual plaintext API key.
 * Injected at construction time. The key never lives in DatadogLogsConfig.
 */
export type SecretResolver = (keyRef: string) => Promise<string>;
/** Datadog regional site identifier. Maps to the canonical intake host. */
export type DatadogSite = 'us1' | 'us3' | 'us5' | 'eu1' | 'us1-fed';
export interface DatadogLogsConfig {
    /** Discriminator for discriminated-union destination config registries. */
    kind: 'datadog-logs';
    /**
     * Datadog site identifier. Determines the intake host.
     * Default: 'us1' (US1 -- http-intake.logs.datadoghq.com).
     */
    site?: DatadogSite;
    /**
     * Override the base URL entirely (useful for tests or proxies).
     * When provided, `site` is ignored.
     * Must be HTTPS unless allowInsecure is true.
     * Example: https://http-intake.logs.datadoghq.com/api/v2/logs
     */
    baseUrl?: string;
    /**
     * KMS/secret-manager reference for the Datadog API key.
     * Never the raw key. Resolved at send-time via SecretResolver.
     * Example: "arn:aws:secretsmanager:us-east-1:123456:secret/dd-api-key"
     */
    apiKeyRef: string;
    /**
     * Datadog source tag (ddsource). Identifies the technology.
     * Default: "aiagents:governance".
     */
    ddsource?: string;
    /**
     * Comma-separated Datadog tags added to every log event.
     * Example: "env:prod,team:governance".
     */
    ddtags?: string;
    /**
     * Service name attached to every log event (service field).
     * Default: "my-cc-governance".
     */
    service?: string;
    /**
     * Hostname attached to every log event.
     * Default: process.env.HOSTNAME or 'unknown'.
     */
    hostname?: string;
    /**
     * Maximum events per HTTP request.
     * Datadog hard limit is 1000. Default: 500 (conservative).
     */
    maxEventsPerRequest?: number;
    /**
     * Maximum uncompressed body size in bytes per request.
     * Datadog hard limit is 5 MB. Default: 4_500_000 (safety margin).
     */
    maxBytesPerRequest?: number;
    /**
     * Enable gzip compression. Default: true.
     * Sends Content-Encoding: gzip.
     */
    compress?: boolean;
    /**
     * Compliance pack IDs governing this destination.
     * MANDATORY -- empty array throws UnboundDataError at construction.
     * Invariant: Thomas Directive 2026-04-22 (pack-binding primacy).
     */
    packBinding: string[];
    /**
     * Directory for dead-letter queue. Required.
     */
    dlqDir: string;
    /**
     * Allow HTTP (non-TLS) endpoints.
     * Default: false. Set true ONLY in test environments.
     */
    allowInsecure?: boolean;
    /** Request timeout in ms. Default: 10000. */
    timeoutMs?: number;
    /** Maximum retry attempts on retryable errors. Default: 3. */
    maxRetries?: number;
    /** Base retry delay in ms. Doubles each attempt with +25% jitter. Default: 1000. */
    retryDelayMs?: number;
}
export interface DeliveryResult {
    success: boolean;
    eventCount: number;
    statusCode?: number;
    attempts: number;
    error?: string;
    deliveredAt?: string;
    /** true = caller may retry later; false = permanent failure. */
    retryable?: boolean;
}
export interface DeadLetterEntry {
    events: EventPayload[];
    error: string;
    attempts: number;
    failedAt: string;
    retryable: boolean;
}
interface DatadogLogEvent {
    ddsource: string;
    ddtags: string;
    service: string;
    hostname: string;
    /** JSON-stringified representation of the governance event. */
    message: string;
    /** Epoch milliseconds. */
    timestamp: number;
}
/**
 * Canonical Datadog Logs Intake host for each supported site.
 * Source: https://docs.datadoghq.com/logs/log_collection/
 */
export declare const SITE_HOSTS: Record<DatadogSite, string>;
/**
 * Resolve the resolved Datadog intake URL from config.
 * baseUrl takes precedence over site. Falls back to us1.
 */
export declare function resolveIntakeUrl(cfg: Pick<DatadogLogsConfig, 'site' | 'baseUrl'>): string;
/**
 * Map a governance EventPayload to a Datadog log object.
 *
 * Mapping table:
 *   message    <- JSON.stringify of event (full payload; Datadog parses nested JSON)
 *   timestamp  <- epoch ms from event.timestamp
 *   ddsource   <- cfg.ddsource
 *   ddtags     <- cfg.ddtags + "event_type:<type>,source:<source>"
 *   service    <- cfg.service
 *   hostname   <- cfg.hostname
 */
export declare function buildLogEvent(event: EventPayload, ddsource: string, ddtags: string, service: string, hostname: string): DatadogLogEvent;
/**
 * Chunk a flat array of events into sub-arrays that respect both the per-request
 * event count limit and the per-request byte size limit.
 *
 * Strategy:
 *   1. Iterate events, accumulating a running JSON array byte count.
 *   2. When adding the next event would exceed maxEvents or maxBytes, flush the
 *      current chunk and start a new one.
 */
export declare function chunkEvents(events: DatadogLogEvent[], maxEvents: number, maxBytes: number): DatadogLogEvent[][];
/**
 * Validate a Datadog intake URL at construction time.
 * Throws a descriptive error on malformed input (PT-DATADOG-2).
 */
export declare function validateIntakeUrl(url: string, allowInsecure: boolean): void;
export declare class DatadogLogsDestination {
    private readonly cfg;
    private readonly resolver;
    private readonly dlqFile;
    private readonly intakeUrl;
    constructor(config: DatadogLogsConfig, resolver: SecretResolver);
    /**
     * Deliver one or more governance events to Datadog Logs Intake.
     *
     * Automatically chunks oversized batches respecting Datadog's per-request
     * limits (1000 events / 5 MB body). Returns an aggregate result for all chunks.
     *
     * The API key is resolved per-call from the secret resolver (PT-DATADOG-1).
     * It is never cached in instance state.
     */
    deliver(events: EventPayload[]): Promise<DeliveryResult>;
    /**
     * Flush alias for API symmetry with SplunkHecDestination.
     * DatadogLogsDestination does not internally buffer events (deliver is
     * always immediate), so flush() is a no-op that returns success.
     */
    flush(): Promise<DeliveryResult>;
    /** Retrieve dead-letter queue entries (most recent `limit` entries). */
    getDLQ(limit?: number): DeadLetterEntry[];
    /**
     * POST one chunk of Datadog log events with retry + DLQ semantics.
     *
     * API key is accepted as a parameter and only used in the DD-API-KEY header.
     * It is never stored in instance state or written to any log (PT-DATADOG-1).
     */
    private postChunk;
    /**
     * Execute the HTTPS POST to the Datadog Logs intake endpoint.
     * The API key is accepted as a parameter and used only in the DD-API-KEY header.
     * It is never stored in instance state or logged.
     */
    private httpPost;
    /** Strip credentials from the intake URL before logging. */
    private safeUrl;
    private writeDLQ;
}
/**
 * Compute exponential backoff with 25% jitter.
 *   delay = base * 2^(attempt-1) + random(0, base * 0.25)
 */
export declare function exponentialDelay(attempt: number, baseMs: number): number;
/**
 * Parse the Retry-After header value.
 * Accepts: integer seconds ("30") or HTTP-date ("Wed, 21 Oct 2015 07:28:00 GMT").
 * Returns milliseconds to wait, or undefined if unparseable.
 */
export declare function parseRetryAfter(headerValue: string | undefined): number | undefined;
export {};
//# sourceMappingURL=datadog-logs.d.ts.map