// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only

/**
 * WU-2735 (INIT-060 WU-7a, ADR-013 §ChannelBridge):
 * Pure domain types for the ChannelBridge port.
 *
 * These types are pure domain: they MUST NOT reference Node `fs`, network
 * sockets, cloud endpoints, or any adapter-specific concept. Both the
 * filesystem adapter (this WU) and the control-plane adapter (WU-2737) shape
 * themselves around these definitions.
 */

/**
 * Branded channel identifier. The bridge mints these during `register`; the
 * brand prevents callers from forging ids from raw strings.
 */
export type ChannelId = string & { readonly __brand: 'sidekick.ChannelId' };

/**
 * Envelope dispatch classification per ADR-013 §4 backpressure split.
 *
 * - `ephemeral` — observational; may fail-silent when transport is down.
 * - `queue` — commands / approvals; must be queued and replayed on reconnect.
 */
export type EnvelopeKind = 'ephemeral' | 'queue';

/**
 * A channel envelope. Kept transport-agnostic: `body` is an opaque
 * JSON-serialisable payload, `content_type` labels it so receivers can dispatch
 * without snooping the body.
 */
export interface ChannelEnvelope {
  /** Unique id per envelope (content-hash or uuid — chosen by the emitter). */
  id: string;
  /** §4 backpressure policy — drives send path (fail-silent vs queued replay). */
  kind: EnvelopeKind;
  /** MIME-like content descriptor, e.g. `application/json`, `text/plain`. */
  content_type: string;
  /** Payload. JSON-serialisable; no host-specific handles. */
  body: unknown;
  /** ISO-8601 UTC timestamp of emit; per-channel ordering key (ADR-013 §3). */
  emitted_at: string;
  /** Optional emitter-supplied metadata (trace ids, correlation keys). */
  metadata?: Readonly<Record<string, unknown>>;
}

/**
 * Bridge registration config — identity under which a channel is opened.
 *
 * The (`provider`, `name`) pair is the canonical identity: re-registering the
 * same pair returns the same `ChannelId` (ADR-013 §ChannelBridge contract
 * rule #3 — idempotent register).
 *
 * `options` is provider-specific bag. The port does NOT inspect it; adapters
 * interpret.
 */
export interface BridgeConfig {
  /** Provider slug — e.g. `filesystem`, `control-plane`. */
  provider: string;
  /** Human-readable channel name scoped within the provider. */
  name: string;
  /** Provider-specific options (paths, tokens, etc.). Opaque to the port. */
  options?: Readonly<Record<string, unknown>>;
}

/**
 * Result of a `send` attempt. `accepted` reflects the port contract: for
 * ephemeral envelopes with an unreachable transport, adapters may return
 * `{ accepted: false, reason: '...' }` rather than throwing (§4 fail-silent).
 */
export interface SendResult {
  accepted: boolean;
  /** Transport-assigned id when the sink confirms receipt (optional). */
  delivery_id?: string;
  /** Reason when `accepted === false` (not meant for programmatic handling). */
  reason?: string;
  /**
   * `true` when the sink recognised `envelope.id` on a registered channel as
   * an at-least-once replay (WU-2737 §Idempotency; cloud contract surface).
   * Adapters that cannot observe dedup SHOULD omit this field.
   */
  deduped?: boolean;
}
