import { aws_sqs, aws_lambda_event_sources, aws_lambda, aws_events_targets } from "aws-cdk-lib";
import lambda from "aws-lambda";
import { Construct } from "constructs";
import { EventSource } from "./event-source";
import { Integration } from "./integration";
import { Iterable } from "./iterable";
import { Serializer } from "./serializer";
export interface Message<M> extends AWS.SQS.Message {
    /**
     * The parsed form of the {@link M} received from the {@link Queue}.
     */
    Message?: M;
}
/**
 * A parsed form of the {@link lambda.SQSEvent} where each of the {@link lambda.SQSRecord}s
 * have been parsed into a {@link SQSRecord}.
 */
export interface SQSEvent<Message> {
    Records: SQSRecord<Message>[];
}
/**
 * A parsed {@link lambda.SQSEvent} containing the parsed form ({@link Message}) of the {@link message}
 * stored as an object on the {@link message} property.
 */
export interface SQSRecord<Message> extends lambda.SQSRecord {
    /**
     * The Message parsed from the {@link body}.
     */
    message: Message;
}
export interface SendMessageRequest<M> extends Omit<AWS.SQS.SendMessageRequest, "MessageBody" | "QueueUrl"> {
    /**
     * The {@link M} to be sent to the {@link Queue}.
     */
    MessageBody: M;
}
export interface SendMessageBatchRequest<M> extends Omit<AWS.SQS.SendMessageBatchRequest, "QueueUrl" | "Entries"> {
    Entries: SendMessageBatchRequestEntry<M>[];
}
export interface SendMessageBatchRequestEntry<M> extends Omit<AWS.SQS.SendMessageBatchRequestEntry, "MessageBody"> {
    MessageBody: M;
}
export interface ReceiveMessageRequest extends Omit<AWS.SQS.ReceiveMessageRequest, "QueueUrl"> {
}
export interface ReceiveMessageResult<M> extends Omit<AWS.SQS.ReceiveMessageResult, "Messages"> {
    /**
     * The {@link M} to be sent to the {@link Queue}.
     */
    Messages?: Message<M>[];
}
interface BaseQueue<Message> {
    /**
     * Delivers a message to the specified queue.
     *
     * ```ts
     * // model the type of data in the Queue
     * interface Message {
     *   key: string;
     * }
     *
     * const queue = new Queue<Message>(scope, id);
     *
     * await queue.sendMessage({
     *   Message: {
     *     key: "value"
     *   },
     * });
     * ```
     *
     * When working with FIFO queues, the {@link SendMessageRequest.MessageDeduplicationId} and
     * {@link SendMessageRequest.MessageGroupId} properties become useful.
     * - `MessageDeduplicationId` - ensures that any duplicate messages sent with the same ID in a
     * 5 minute time window are ignored, ensuring that exactly one of those messages were delivered. If
     * your FIFO Queue is configured with {@link aws_sqs.DeduplicationScope.MESSAGE_GROUP} then duplicate
     * IDs are only considered duplicates when they also have the same `MessageGroupId`, otherwise
     * de-duplication is applied globally. Global de-duplication limits the throughput of your entire Queue
     * to 300-3000 messages per second, so use it only when you absolutely need.
     * - `MessageGroupId` - Messages with the same MessageGroupId are guaranteed to be processed by consumers
     * in FIFO order. The first message sent is the first message received. Subsequent messages cannot be
     * processed until prior messages are deleted from the Queue.
     *
     * ```ts
     * await queue.sendMessage({
     *   Message: message,
     *
     *   // prevent delivering this message more than once in a 5 minute time window
     *   MessageDeduplicationId: message.requestId,
     *
     *   // ensure messages with the same userId are processed in order
     *   // only care about de-duplication in the scope of a single `userId`.
     *   MessageGroupId: message.userId
     * });
     * ```
     */
    sendMessage(input: SendMessageRequest<Message>): Promise<AWS.SQS.SendMessageResult>;
    /**
     * Delivers up to ten messages to the specified queue. This is a batch version of
     * {@link sendMessage}. The maximum allowed individual message size and the maximum
     * total payload size (the sum of the individual lengths of all of the batched messages)
     * are both 256 KB (262,144 bytes).
     *
     * ```ts
     * // model the type of data in the Queue
     * interface Message {
     *   key: string;
     * }
     *
     * // create a Queue
     * const queue = new Queue<Message>(scope, id);
     *
     * // send a batch of messages to the Queue
     * await queue.sendMessageBatch({
     *   Entries: [{
     *     Id: "1",
     *     // the message is a `Message` type - it will be automatically serialized as a JSON string
     *     Message: {
     *       key: "value"
     *     }
     *   }]
     * })
     * ```
     *
     * The result of sending each message is reported individually in the response.
     * Because the batch request can result in a combination of successful and unsuccessful
     * actions, you should check for batch errors even when the call returns an HTTP status
     * code of 200.
     *
     * ```ts
     * async function sendWithRetries(entries: SendMessageRequestEntry<Message>) {
     *   // try and send the batch of messages
     *   const response = await queue.sendMessageBatch({
     *     Entries: entries,
     *   });
     *
     *   if (response.Failed.length > 0) {
     *     // try and send the failed messages again
     *     await sendWithRetries(response.Failed.map((failed) =>
     *       entries.find((entry) => entry.Id === failed.Id)
     *     ));
     *   }
     * }
     * ```
     *
     * When working with FIFO queues, the {@link SendMessageRequest.MessageDeduplicationId} and
     * {@link SendMessageRequest.MessageGroupId} properties become useful.
     * - `MessageDeduplicationId` - ensures that any duplicate messages sent with the same ID in a
     * 5 minute time window are ignored, ensuring that exactly one of those messages were delivered. If
     * your FIFO Queue is configured with {@link aws_sqs.DeduplicationScope.MESSAGE_GROUP} then duplicate
     * IDs are only considered duplicates when they also have the same `MessageGroupId`, otherwise
     * de-duplication is applied globally. Global de-duplication limits the throughput of your entire Queue
     * to 300-3000 messages per second, so use it only when you absolutely need.
     * - `MessageGroupId` - Messages with the same MessageGroupId are guaranteed to be processed by consumers
     * in FIFO order. The first message sent is the first message received. Subsequent messages cannot be
     * processed until prior messages are deleted from the Queue.
     *
     * ```ts
     * await queue.sendMessageBatch({
     *   Entries: [{
     *     Message: message,
     *
     *     // prevent delivering this message more than once in a 5 minute time window
     *     MessageDeduplicationId: message.requestId,
     *
     *     // ensure messages with the same userId are processed in order
     *     // only care about de-duplication in the scope of a single `userId`.
     *     MessageGroupId: message.userId
     *   }]
     * });
     * ```
     *
     * If you don't specify the DelaySeconds parameter for an entry, Amazon SQS uses the default value
     * for the queue. Some actions take lists of parameters. These lists are specified using the
     * `param.n` notation - values of n are integers starting from 1.
     *
     * For example, a parameter list with two elements looks like this:
     * ```
     * &amp;AttributeName.1=first
     * &amp;AttributeName.2=second
     * ```
     */
    sendMessageBatch(input: SendMessageBatchRequest<Message>): Promise<AWS.SQS.SendMessageBatchResult>;
    /**
     * Retrieves one or more messages (up to 10), from the specified queue.
     * Using the WaitTimeSeconds parameter enables long-poll support.
     * For more information, see Amazon SQS Long Polling in the Amazon SQS Developer Guide.
     *
     * Short poll is the default behavior where a weighted random set of machines is sampled
     * on a ReceiveMessage call. Thus, only the messages on the sampled machines are returned.
     *
     * If the number of messages in the queue is small (fewer than 1,000), you most likely get
     * fewer messages than you requested per ReceiveMessage call. If the number of messages in
     * the queue is extremely small, you might not receive any messages in a particular ReceiveMessage
     * response. If this happens, repeat the request
     *
     * For each message returned, the response includes the following:
     * - The message body.
     * - An MD5 digest of the message body. For information about MD5, see RFC1321.
     * - The MessageId you received when you sent the message to the queue.
     * - The receipt handle - the identifier you must provide when deleting the message.
     * - The message attributes.
     * - An MD5 digest of the message attributes.
     *
     * For more information, see [Queue and Message Identifiers](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-queue-message-identifiers.html)
     * in the Amazon SQS Developer Guide.
     *
     * You can provide the VisibilityTimeout parameter in your request. The parameter is applied to
     * the messages that Amazon SQS returns in the response. If you don't include the parameter, the
     * overall visibility timeout for the queue is used for the returned messages. For more information,
     * see [Visibility Timeout](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) in the Amazon SQS Developer Guide.
     *
     * ```ts
     * queue.receiveMessage({
     *   // we will have up to 60 seconds to process the received messages and delete them from the
     *   // queue until they will again be visible to other consumers.
     *   VisibilityTimeout: 60,
     * })
     * ```
     *
     * A message that isn't deleted or a message whose visibility isn't extended before the visibility
     * timeout expires counts as a failed receive. Depending on the configuration of the queue, the
     * message might be sent to the dead-letter queue.
     *
     * ```ts
     * const dlq = new Queue<Message>(scope, id);
     * const queue = new Queue<Message>(scope, id, {
     *   deadLetterQueue: dql
     * });
     *
     * dlq.messages().forEach(async (deadMessage) => {
     *   console.log("oopsy whoopsy", deadMessage);
     * });
     * ```
     *
     * In the future, new attributes might be added. If you write code that calls this action, we recommend
     * that you structure your code so that it can handle new attributes gracefully.
     */
    receiveMessage(input?: ReceiveMessageRequest): Promise<ReceiveMessageResult<Message>>;
    /**
     * Deletes the messages in this queue.
     * ```ts
     * await queue.purge();
     * ```
     *
     * When you use the PurgeQueue action, you can't retrieve any messages deleted from a
     * queue. The message deletion process takes up to 60 seconds. We recommend waiting
     * for 60 seconds regardless of your queue's size.
     *
     * Messages sent to the queue before you call PurgeQueue might be received but are deleted within the
     * next minute. Messages sent to the queue after you call PurgeQueue might be deleted while the queue
     * is being purged.
     */
    purge(): Promise<{}>;
}
declare abstract class BaseQueue<Message> extends EventSource<aws_sqs.IQueue, QueueProps<Message>, lambda.SQSEvent, SQSEvent<Message>, lambda.SQSBatchResponse | void, aws_lambda_event_sources.SqsEventSourceProps> implements Integration<"Queue", () => any> {
    /**
     * @hidden
     */
    static readonly FunctionlessType = "Queue";
    /**
     * @hidden
     */
    readonly functionlessKind = "Queue";
    /**
     * @hidden
     */
    readonly kind = "Queue";
    /**
     * @hidden
     */
    readonly __functionBrand: () => Promise<void>;
    /**
     * The ARN of this queue
     * @attribute
     */
    get queueArn(): string;
    /**
     * The Name of this queue
     * @attribute
     */
    get queueName(): string;
    /**
     * The URL of this queue
     * @attribute
     */
    get queueUrl(): string;
    readonly serializer: Serializer<Message>;
    constructor(scope: Construct, id: string, props: QueueProps<Message>);
    constructor(resource: aws_sqs.IQueue, props: QueueProps<Message>);
    /**
     * Returns an {@link Iterable} instance that can be used to process messages
     * in this {@link Queue}.
     *
     * #### Example Usage
     * ```ts
     * const myTable = new Table<Message, "id">(scope, "table", { .. });
     * const queue = new Queue(scope, "queue");
     *
     * queue.messages().forEach(async (message) => {
     *   // put each message from the Queue into a Table
     *   await $AWS.DynamoDB.PutItem({
     *     Table: myTable,
     *     Item: {
     *       id: { S: message.id },
     *       message: { S: JSON.stringify(message) }
     *     }
     *   })
     * });
     * ```
     */
    messages(): Iterable<Message, lambda.SQSEvent, SQSEvent<Message>, SQSRecord<Message>, lambda.SQSBatchResponse, aws_lambda_event_sources.SqsEventSourceProps>;
    /**
     * @hidden
     */
    protected createResource(scope: Construct, id: string, config: QueueProps<Message>): aws_sqs.IQueue;
    /**
     * @hidden
     */
    protected createEventSource(config: aws_lambda_event_sources.SqsEventSourceProps): aws_lambda.IEventSource;
    /**
     * @hidden
     */
    protected createParser(): (event: lambda.SQSEvent) => SQSEvent<Message>;
    /**
     * @hidden
     */
    createResponseHandler(): (failed: lambda.SQSRecord[]) => lambda.SQSBatchResponse;
    /**
     * @hidden
     */
    createGetPayload(): (event: SQSRecord<Message>) => any;
    /**
     * Support `bus.when(...).pipe(queue)`
     *
     * @hidden
     */
    readonly eventBus: import("./event-bridge/event-bus").EventBusTargetIntegration<Message, Omit<aws_events_targets.SqsQueueProps, "message"> | undefined>;
}
export interface DeadLetterQueue<Message> extends Omit<aws_sqs.DeadLetterQueue, "queue"> {
    /**
     * The dead-letter queue to which Amazon SQS moves messages after the value of maxReceiveCount is exceeded.
     */
    queue: IQueue<Message>;
}
export interface QueueProps<Message> extends Omit<aws_sqs.QueueProps, "deadLetterQueue"> {
    /**
     * Specifies the {@link Serializer} instance to use for serializing messages
     * sent to the Queue and deserializing messages received from the Queue.
     *
     * @default {@link JsonSerializer}
     */
    serializer?: Serializer<Message>;
    /**
     * Options related to using the Queue in a {@link Function}.S
     */
    lambda?: {
        /**
         * An optional callback which allows customization of the queue url when using Queue APIs in lambda.
         *
         * For example, when using Functionless with `localstack`, the queue url in CDK is different
         * from the queue url in the lambda execution environment.
         *
         * ```ts
         * lambdaQueueUrlRetriever: (queueUrl) =>
         *    process.env.LOCALSTACK_HOSTNAME
         *       ? queueUrl.replace("localhost", process.env.LOCALSTACK_HOSTNAME)
         *       : queueUrl,
         * ```
         */
        queueUrlRetriever?: (queueUrl: string) => string;
    };
    /**
     * Send messages to this queue if they were unsuccessfully dequeued a number of times.
     *
     * @default no dead-letter queue
     */
    deadLetterQueue?: DeadLetterQueue<Message>;
}
export interface IQueue<T = any> extends BaseQueue<T> {
}
/**
 * A SQS Queue. Each of the messages stored in the Queue are of type {@link T}.
 *
 * #### Example Usage
 * ```ts
 * // create a DynamoDB Table
 * const myTable = new Table<Message, "id">(this, "table", { .. });
 *
 * const queue = new Queue(this, "queue");
 *
 * // create a Function to process each of the messages in the queues
 * queue.messages().forEach(async (message) => {
 *   // put each message from the Queue into a Table
 *   await $AWS.DynamoDB.PutItem({
 *     Table: myTable,
 *     Item: {
 *       id: { S: message.id },
 *       message: { S: JSON.stringify(message) }
 *     }
 *   })
 * });
 *
 * // for testing purpose, create an ExpressStepFunction to send messages to the queue
 * new ExpressStepFunction(this, "func", async () => {
 *   await queue.sendMessage({
 *     id: "message id",
 *     data: "message data"
 *   })
 * });
 * ```
 */
export declare class Queue<T = any> extends BaseQueue<T> implements IQueue<T> {
    constructor(scope: Construct, id: string, props?: QueueProps<T>);
}
export {};
//# sourceMappingURL=queue.d.ts.map