import { type SpanOptions } from '@opentelemetry/api';
import { type ArvoContract, type ArvoEvent } from 'arvo-core';
import AbstractArvoEventHandler from '../AbstractArvoEventHandler';
import type { ArvoEventHandlerOpenTelemetryOptions } from '../types';
import type { ArvoEventHandlerFunction, IArvoEventHandler } from './types';
/**
 * `ArvoEventHandler` is the foundational component for building stateless,
 * contract-bound services in the Arvo system.
 *
 * It enforces strict contract validation, version-aware handler resolution,
 * and safe, observable event emission — all while maintaining type safety,
 * traceability, and support for multi-domain workflows.
 *
 * ## What It Does
 * - Ensures incoming events match the contract's `type` and `dataschema`
 * - Resolves the correct contract version using `dataschema`
 * - Validates input and output data via Zod schemas
 * - Executes the version-specific handler function
 * - Emits one or more response events based on the handler result
 * - Supports multi-domain broadcasting via `domain[]` on the emitted events
 * - Automatically emits system error events (`sys.*.error`) on failure
 * - Integrates deeply with OpenTelemetry for tracing and observability
 *
 * ## Error Boundaries
 * ArvoEventHandler enforces a clear separation between:
 *
 * - **Violations** — structural, schema, or config errors that break the contract.
 *   These are thrown and must be handled explicitly by the caller.
 *
 * - **System Errors** — runtime exceptions during execution that are caught and
 *   emitted as standardized `sys.<contract>.error` events.
 *
 * ## Domain Broadcasting
 * The handler supports multi-domain event distribution. When the handler
 * returns an event with a `domain` array, it is broadcast to one or more
 * routing contexts.
 *
 * ### System Error Domain Control
 * By default, system error events are broadcast into the source event’s domain,
 * the handler’s contract domain, and the `null` domain. This fallback ensures errors
 * are visible across all relevant contexts. Developers can override this behavior
 * using the optional `systemErrorDomain` field to specify an explicit set of
 * domain values, including symbolic constants from {@link ArvoDomain}.
 *
 * ### Supported Domain Values:
 * - A **concrete domain string** like `'audit.orders'` or `'human.review'`
 * - `null` to emit with no domain (standard internal flow)
 * - A **symbolic reference** from {@link ArvoDomain}
 *
 * ### Domain Resolution Rules:
 * - Each item in the `domain` array is resolved via {@link resolveEventDomain}
 * - Duplicate domains are deduplicated before emitting
 * - If `domain` is omitted entirely, Arvo defaults to `[null]`
 *
 * ### Example:
 * ```ts
 * return {
 *   type: 'evt.user.registered',
 *   data: { ... },
 *   domain: ['analytics', ArvoDomain.FROM_TRIGGERING_EVENT, null]
 * };
 * ```
 * This would emit at most 3 copies of the event, domained to:
 * - `'analytics'`
 * - the domain of the incoming event
 * - no domain (default)
 *
 * ### Domain Usage Guidance
 *
 * > **Avoid setting `contract.domain` unless fully intentional.**
 * 99% emitted event should default to `null` (standard processing pipeline).
 *
 * Contract-level domains enforce implicit routing for every emitted event
 * in that handler, making the behavior harder to override and debug.
 *
 * Prefer:
 * - Explicit per-event `domain` values in handler output
 * - Using `null` or symbolic constants to control domain cleanly
 *
 * ## When to Use Domains
 * Use domains when handling for specialized contexts:
 * - `'human.review'` → for human-in-the-loop steps
 * - `'analytics.workflow'` → to pipe events into observability systems
 * - `'external.partner.sync'` → to route to external services
 */
export default class ArvoEventHandler<TContract extends ArvoContract> extends AbstractArvoEventHandler {
    /** Contract instance that defines the event schema and validation rules */
    readonly contract: TContract;
    /** Computational cost metric associated with event handling operations */
    readonly executionunits: number;
    /** OpenTelemetry configuration for event handling spans */
    readonly spanOptions: SpanOptions;
    /** Version-specific event handler implementation map */
    readonly handler: ArvoEventHandlerFunction<TContract>;
    /** The source identifier for events produced by this handler */
    get source(): TContract['type'];
    readonly systemErrorDomain?: (string | null)[];
    /**
     * The contract-defined domain for this handler, used as the default domain for emitted events.
     * Can be overridden by individual handler implementations for cross-domain workflows.
     * Returns null if no domain is specified, indicating standard processing context.
     */
    get domain(): string | null;
    /**
     * Initializes a new ArvoEventHandler instance with the specified contract and configuration.
     * Validates handler implementations against contract versions during initialization.
     *
     * The constructor ensures that handler implementations exist for all supported contract
     * versions and configures OpenTelemetry span attributes for monitoring event handling.
     *
     * @param param - Handler configuration including contract, execution units, and handler implementations
     * @throws When handler implementations are missing for any contract version
     */
    constructor(param: IArvoEventHandler<TContract>);
    /**
     * Processes an incoming event according to the handler's contract specifications. This method
     * handles the complete lifecycle of event processing including validation, execution, error
     * handling, and multi-domain event broadcasting, while maintaining detailed telemetry through OpenTelemetry.
     *
     * @param event - The incoming event to process
     * @param opentelemetry - Configuration for OpenTelemetry context inheritance, defaults to inheriting from the event
     * @returns Promise resolving to a structured result containing an array of output events
     * @returns Structured response containing:
     *   - `events`: Array of events to be emitted (may contain multiple events per handler output due to domain broadcasting)
     *
     * @throws {ContractViolation} when input or output event data violates the contract schema,
     *                             or when event emission fails due to invalid data
     * @throws {ConfigViolation} when event type doesn't match contract type, when the
     *                           contract version expected by the event does not exist
     *                           in handler configuration, or when contract URI mismatch occurs
     * @throws {ExecutionViolation} for explicitly handled runtime errors that should bubble up
     */
    execute(event: ArvoEvent, opentelemetry?: ArvoEventHandlerOpenTelemetryOptions): Promise<{
        events: ArvoEvent[];
    }>;
    /**
     * Provides access to the system error event schema configuration.
     *
     * The schema defines the structure of error events emitted during execution failures.
     * These events are automatically generated when runtime errors occur and follow a
     * standardized format for consistent error handling across the system.
     *
     * Error events follow the naming convention: `sys.<contract-type>.error`
     *
     * @example
     * For a contract handling 'com.user.create' events, system error events
     * will have the type 'sys.com.user.create.error'
     *
     * @returns The error event schema containing type and validation rules
     */
    get systemErrorSchema(): import("arvo-core").ArvoContractRecord<`sys.${string}.error`, import("zod").ZodObject<{
        errorName: import("zod").ZodString;
        errorMessage: import("zod").ZodString;
        errorStack: import("zod").ZodNullable<import("zod").ZodString>;
    }, "strip", import("zod").ZodTypeAny, {
        errorName: string;
        errorMessage: string;
        errorStack: string | null;
    }, {
        errorName: string;
        errorMessage: string;
        errorStack: string | null;
    }>>;
}
