/**
 * ServiceContract — Typed actor interfaces for the Matrix bus.
 *
 * One contract declaration serves as:
 *   - The type (TypeScript infers from const)
 *   - The intent (passed to resolve())
 *   - The validator (runtime payload checking)
 *   - The $introspect response (serialized as JSON)
 *
 * Follows COM IUnknown/IDL: one source of truth, everything derived.
 * See: ARCHITECTURE/ARCHITECTURE-SERVICE-CONTRACTS.md
 */

// ── Contract Types (runtime objects + compile-time inference) ─────────────

/** A field in a payload or response — type, required, description. */
export interface FieldContract {
  readonly type: string;
  readonly required?: boolean;
  readonly description?: string;
}

/** An operation's full contract — payload shape, response shape, errors. */
export interface OperationContract {
  readonly description: string;
  readonly payload: Record<string, FieldContract>;
  readonly response: Record<string, FieldContract>;
  readonly errors?: ReadonlyArray<{ code: string; description: string }>;
}

/** A service contract — id, description, and all operations. */
export interface ServiceContract {
  readonly id: string;
  readonly description: string;
  readonly ops: Record<string, OperationContract>;
}

// ── Actor Contract (static contract on actor class) ──────────────────────

/**
 * An interface within an actor contract — groups related ops by dot-prefix.
 * e.g. "health" interface has ops: status, component, setThresholds.
 */
export interface InterfaceContract {
  readonly description: string;
  readonly ops: Record<string, OperationContract>;
}

/**
 * The unified contract an actor declares via `static contract`.
 * Groups ops by interface (dot-prefix). Replaces scattered static accepts,
 * outputSchemas, and errorSpecs with one object.
 *
 * Example:
 *   static contract: ActorContract = {
 *     interfaces: {
 *       health: {
 *         description: 'System health monitoring',
 *         ops: {
 *           status: { description: 'Get health status', payload: {}, response: { ok: { type: 'boolean' } } },
 *         }
 *       }
 *     }
 *   };
 */
export interface ActorContract {
  readonly interfaces: Record<string, InterfaceContract>;
}

// ── IActorService (COM's IUnknown equivalent) ────────────────────────────

/**
 * Base interface every resolved service implements.
 * Like COM's IUnknown — universal, always available, supports capability queries.
 */
export interface IActorService {
  /** Bus mount path where this service lives. */
  readonly mount: string;

  /** The full contract (type library). */
  readonly contract: ServiceContract;

  /** QueryInterface — does this service support a given operation? */
  supports(op: string): boolean;

  /** Invoke an operation. Validates payload against contract. */
  invoke(op: string, payload?: Record<string, unknown>): Promise<unknown>;
}

// ── Intent Resolution ────────────────────────────────────────────────────

/**
 * Intent provider — resolves a contract to a service proxy.
 * Context implements this. Bus scanner implements this. Federation
 * implements this. All return the same IActorService proxy.
 */
export interface IIntentProvider {
  resolve(contract: ServiceContract): Promise<IActorService | undefined>;
}

/**
 * Semantic intent provider — can match by natural language description.
 * Future: AI-assisted service discovery.
 */
export interface ISemanticIntentProvider extends IIntentProvider {
  resolveByDescription(description: string): Promise<IActorService | undefined>;
}
