import { Temporal } from "@js-temporal/polyfill";
import { URLPattern } from "urlpattern-polyfill";

//#region federation/mq.d.ts
/**
 * Additional options for enqueuing a message in a queue.
 *
 * @since 0.5.0
 */
interface MessageQueueEnqueueOptions {
  /**
   * The delay before the message is enqueued.  No delay by default.
   *
   * It must not be negative.
   */
  delay?: Temporal.Duration;
}
/**
 * Additional options for listening to a message queue.
 *
 * @since 1.0.0
 */
interface MessageQueueListenOptions {
  /**
   * The signal to abort listening to the message queue.
   */
  signal?: AbortSignal;
}
/**
 * An abstract interface for a message queue.
 *
 * @since 0.5.0
 */
interface MessageQueue {
  /**
   * Whether the message queue backend provides native retry mechanisms.
   * When `true`, Fedify will skip its own retry logic and rely on the backend
   * to handle retries. When `false` or omitted, Fedify will handle retries
   * using its own retry policies.
   *
   * @default `false`
   * @since 1.7.0
   */
  readonly nativeRetrial?: boolean;
  /**
   * Enqueues a message in the queue.
   * @param message The message to enqueue.
   * @param options Additional options for enqueuing the message.
   */
  enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
  /**
   * Enqueues multiple messages in the queue.  This operation is optional,
   * and may not be supported by all implementations.  If not supported,
   * Fedify will invoke {@link enqueue} for each message.
   *
   * @param messages The messages to enqueue.
   * @param options Additional options for enqueuing the messages.
   */
  enqueueMany?: (messages: any[], options?: MessageQueueEnqueueOptions) => Promise<void>;
  /**
   * Listens for messages in the queue.
   * @param handler The handler for messages in the queue.
   * @param options Additional options for listening to the message queue.
   * @returns A promise that resolves when the listening is done.  It never
   *          rejects, and is resolved when the signal is aborted.  If no
   *          signal is provided, it never resolves.
   */
  listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
}
/**
 * Additional options for {@link InProcessMessageQueue}.
 * @since 1.0.0
 */
interface InProcessMessageQueueOptions {
  /**
   * The interval to poll for messages in the queue.  5 seconds by default.
   * @default `{ seconds: 5 }`
   */
  pollInterval?: Temporal.Duration | Temporal.DurationLike;
}
/**
 * A message queue that processes messages in the same process.
 * Do not use this in production as it does neither persist messages nor
 * distribute them across multiple processes.
 *
 * @since 0.5.0
 */
declare class InProcessMessageQueue implements MessageQueue {
  #private;
  /**
   * In-process message queue does not provide native retry mechanisms.
   * @since 1.7.0
   */
  readonly nativeRetrial = false;
  /**
   * Constructs a new {@link InProcessMessageQueue} with the given options.
   * @param options Additional options for the in-process message queue.
   */
  constructor(options?: InProcessMessageQueueOptions);
  enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
  enqueueMany(messages: any[], options?: MessageQueueEnqueueOptions): Promise<void>;
  listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
}
/**
 * A message queue that processes messages in parallel.  It takes another
 * {@link MessageQueue}, and processes messages in parallel up to a certain
 * number of workers.
 *
 * Actually, it's rather a decorator than a queue itself.
 *
 * Note that the workers do not run in truly parallel, in the sense that they
 * are not running in separate threads or processes.  They are running in the
 * same process, but are scheduled to run in parallel.  Hence, this is useful
 * for I/O-bound tasks, but not for CPU-bound tasks, which is okay for Fedify's
 * workloads.
 *
 * @since 1.0.0
 */
declare class ParallelMessageQueue implements MessageQueue {
  #private;
  readonly queue: MessageQueue;
  readonly workers: number;
  /**
   * Inherits the native retry capability from the wrapped queue.
   * @since 1.7.0
   */
  readonly nativeRetrial?: boolean;
  /**
   * Constructs a new {@link ParallelMessageQueue} with the given queue and
   * number of workers.
   * @param queue The message queue to use under the hood.  Note that
   *              {@link ParallelMessageQueue} cannot be nested.
   * @param workers The number of workers to process messages in parallel.
   * @throws {TypeError} If the given queue is an instance of
   *                     {@link ParallelMessageQueue}.
   */
  constructor(queue: MessageQueue, workers: number);
  enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
  enqueueMany(messages: any[], options?: MessageQueueEnqueueOptions): Promise<void>;
  listen(handler: (message: any) => Promise<void> | void, options?: MessageQueueListenOptions): Promise<void>;
}
//#endregion
export { InProcessMessageQueue, InProcessMessageQueueOptions, MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions, ParallelMessageQueue };