import { Link } from "../common";

/**
 * Contextual information provided to every operation handler method.
 *
 * @experimental
 */
export interface OperationContext {
  /**
   * Name of the service that contains the operation.
   */
  readonly service: string;

  /**
   * Name of the operation.
   */
  readonly operation: string;

  /**
   * Request header fields.
   */
  readonly headers: Record<string, string>;

  /**
   * An AbortSignal that is signaled when the current request is canceled, e.g. because the request
   * timed out or the client disconnected.
   *
   * The framework will cancel the abort controller with an unspecified error type. The handler
   * must rethrow the error object to confirm cancelation. The handler may ignore cancelation
   * and return a result anyway, but there is no guarantee that the client will still be waiting
   * for the result of that request.
   *
   * Note that cancelation of the current _request_ is not the same thing - and does not relate
   * with - cancelation of the _operation_ itself, which is notified by calling the
   * {@link OperationHandler.cancel} method.
   */
  readonly abortSignal: AbortSignal;

  /**
   * Get the deadline for the operation handler method.
   *
   * Note that this is the time by which the current _request_ should complete,
   * not the _operation_'s deadline.
   */
  readonly requestDeadline?: Date;
}

/**
 * Context for the {@link OperationHandler.start} method.
 *
 * @experimental
 */
export interface StartOperationContext extends OperationContext {
  /**
   * Callbacks are used to deliver completion of async operations.
   *
   * A callback URL may optionally be provided by the client and should be called by this handler
   * upon completion if the started operation is async.
   */
  readonly callbackUrl?: string;

  /**
   * Optional header fields set by a client that are required to be attached to the callback request
   * when an asynchronous operation completes.
   */
  readonly callbackHeaders?: Record<string, string>;

  /**
   * Request ID that may be used by the server handler to dedupe a start request.
   * By default a v4 UUID will be generated by the client.
   */
  readonly requestId: string;

  /**
   * Links received in the request.
   *
   * This list is automatically populated when handling a start request. Handlers may use these
   * links, for example to add information about the caller to a resource associated with the
   * operation execution.
   */
  readonly inboundLinks: Link[];

  /**
   * Links to be returned by the handler.
   *
   * This list is initially empty. Handlers may add to this list, for example links describing
   * resources associated with the operation execution that may be of use to the caller.
   */
  readonly outboundLinks: Link[];
}

/**
 * Context for the {@link OperationHandler.cancel} method.
 *
 * @experimental
 */
export type CancelOperationContext = OperationContext;
