import { __decorateMetadata } from "../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateMetadata.mjs";
import { __decorate } from "../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.mjs";
import { DidCommOutboundMessageContext } from "../../models/DidCommOutboundMessageContext.mjs";
import "../../models/index.mjs";
import { Subject } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/Subject.mjs";
import { ReplaySubject } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/ReplaySubject.mjs";
import { firstValueFrom } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/firstValueFrom.mjs";
import { timeout } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/operators/timeout.mjs";
import { filter } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/operators/filter.mjs";
import { first } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/operators/first.mjs";
import { takeUntil } from "../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/esm5/internal/operators/takeUntil.mjs";
import { DidCommModuleConfig } from "../../DidCommModuleConfig.mjs";
import { __decorateParam } from "../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateParam.mjs";
import { DidCommConnectionService } from "../connections/services/DidCommConnectionService.mjs";
import { DidCommMessageSender } from "../../DidCommMessageSender.mjs";
import "../connections/services/index.mjs";
import { DidCommMessagePickupEventTypes } from "./DidCommMessagePickupEvents.mjs";
import { DidCommMessagePickupModuleConfig } from "./DidCommMessagePickupModuleConfig.mjs";
import { DidCommMessagePickupSessionService } from "./services/DidCommMessagePickupSessionService.mjs";
import { AgentContext, CredoError, EventEmitter, InjectionSymbols, inject, injectable } from "@credo-ts/core";

//#region ../didcomm/src/modules/message-pickup/DidCommMessagePickupApi.ts
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
let DidCommMessagePickupApi = class DidCommMessagePickupApi$1 {
	constructor(messageSender, agentContext, connectionService, eventEmitter, messagePickupSessionService, config, stop$, logger) {
		this.messageSender = messageSender;
		this.connectionService = connectionService;
		this.agentContext = agentContext;
		this.eventEmitter = eventEmitter;
		this.config = config;
		this.messagePickupSessionService = messagePickupSessionService;
		this.stop$ = stop$;
		this.logger = logger;
	}
	getProtocol(protocolVersion) {
		const protocol = this.config.protocols.find((protocol$1) => protocol$1.version === protocolVersion);
		if (!protocol) throw new CredoError(`No message pickup protocol registered for protocol version ${protocolVersion}`);
		return protocol;
	}
	/**
	* Add an encrypted message to the message pickup queue
	*
	* @param options: connectionId associated to the message and the encrypted message itself
	*/
	async queueMessage(options) {
		this.logger.debug("Queuing message...");
		const { connectionId, message, recipientDids } = options;
		const connectionRecord = await this.connectionService.getById(this.agentContext, connectionId);
		await this.agentContext.dependencyManager.resolve(DidCommModuleConfig).queueTransportRepository.addMessage(this.agentContext, {
			connectionId: connectionRecord.id,
			recipientDids,
			payload: message
		});
	}
	/**
	* Get current active live mode message pickup session for a given connection. Undefined if no active session found
	*
	* @param options connection id and optional role
	* @returns live mode session
	*/
	async getLiveModeSession(options) {
		const { connectionId, role } = options;
		return this.messagePickupSessionService.getLiveSessionByConnectionId(this.agentContext, {
			connectionId,
			role
		});
	}
	/**
	* Deliver specific messages to an active live mode pickup session through message pickup protocol.
	*
	* This will deliver the messages regardless of the state of the message pickup queue, meaning that
	* any message stuck there should be sent separately (e.g. using deliverQU).
	*
	* @param options: pickup session id and the messages to deliver
	*/
	async deliverMessages(options) {
		const { pickupSessionId, messages } = options;
		const session = this.messagePickupSessionService.getLiveSession(this.agentContext, pickupSessionId);
		if (!session) throw new CredoError(`No active live mode session found with id ${pickupSessionId}`);
		const connectionRecord = await this.connectionService.getById(this.agentContext, session.connectionId);
		const createDeliveryReturn = await this.getProtocol(session.protocolVersion).createDeliveryMessage(this.agentContext, {
			connectionRecord,
			messages
		});
		if (createDeliveryReturn) await this.messageSender.sendMessage(new DidCommOutboundMessageContext(createDeliveryReturn.message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		}), { transportPriority: { schemes: ["wss", "ws"] } });
	}
	/**
	* Deliver messages in the Message Pickup Queue for a given live mode session and key (if specified).
	*
	* This will retrieve messages up to 'batchSize' messages from the queue and deliver it through the
	* corresponding Message Pickup protocol. If there are more than 'batchSize' messages in the queue,
	* the recipient may request remaining messages after receiving the first batch of messages.
	*
	*/
	async deliverMessagesFromQueue(options) {
		this.logger.debug("Delivering queued messages");
		const { pickupSessionId, recipientDid: recipientKey, batchSize } = options;
		const session = this.messagePickupSessionService.getLiveSession(this.agentContext, pickupSessionId);
		if (!session) throw new CredoError(`No active live mode session found with id ${pickupSessionId}`);
		const connectionRecord = await this.connectionService.getById(this.agentContext, session.connectionId);
		const deliverMessagesReturn = await this.getProtocol(session.protocolVersion).createDeliveryMessage(this.agentContext, {
			connectionRecord,
			recipientKey,
			batchSize
		});
		if (deliverMessagesReturn) await this.messageSender.sendMessage(new DidCommOutboundMessageContext(deliverMessagesReturn.message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		}), { transportPriority: { schemes: ["wss", "ws"] } });
	}
	/**
	* Pickup queued messages from a message holder. It attempts to retrieve all current messages from the
	* queue, receiving up to `batchSize` messages per batch retrieval.
	*
	* By default, this method only waits until the initial pick-up request is sent. Use `options.awaitCompletion`
	* if you want to wait until all messages are effectively retrieved.
	*
	* @param options connectionId, protocol version to use and batch size, awaitCompletion,
	* awaitCompletionTimeoutMs
	*/
	async pickupMessages(options) {
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		const { message } = await this.getProtocol(options.protocolVersion).createPickupMessage(this.agentContext, {
			connectionRecord,
			batchSize: options.batchSize,
			recipientDid: options.recipientDid
		});
		const outboundMessageContext = new DidCommOutboundMessageContext(message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		});
		const replaySubject = new ReplaySubject(1);
		if (options.awaitCompletion) this.eventEmitter.observable(DidCommMessagePickupEventTypes.MessagePickupCompleted).pipe(takeUntil(this.stop$), filter((e) => e.payload.connection.id === connectionRecord.id), first(), timeout({
			first: options.awaitCompletionTimeoutMs ?? 1e4,
			meta: "DidCommMessagePickupApi.pickupMessages"
		})).subscribe(replaySubject);
		await this.messageSender.sendMessage(outboundMessageContext, { transportPriority: { schemes: ["wss", "ws"] } });
		if (options.awaitCompletion) await firstValueFrom(replaySubject);
	}
	/**
	* Enable or disable Live Delivery mode as a recipient. Depending on the message pickup protocol used,
	* after receiving a response from the mediator the agent might retrieve any pending message.
	*
	* @param options connectionId, protocol version to use and boolean to enable/disable Live Mode
	*/
	async setLiveDeliveryMode(options) {
		const connectionRecord = await this.connectionService.getById(this.agentContext, options.connectionId);
		const { message } = await this.getProtocol(options.protocolVersion).setLiveDeliveryMode(this.agentContext, {
			connectionRecord,
			liveDelivery: options.liveDelivery
		});
		await this.messageSender.sendMessage(new DidCommOutboundMessageContext(message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		}), { transportPriority: {
			schemes: ["wss", "ws"],
			restrictive: options.liveDelivery
		} });
	}
};
DidCommMessagePickupApi = __decorate([
	injectable(),
	__decorateParam(6, inject(InjectionSymbols.Stop$)),
	__decorateParam(7, inject(InjectionSymbols.Logger)),
	__decorateMetadata("design:paramtypes", [
		typeof (_ref = typeof DidCommMessageSender !== "undefined" && DidCommMessageSender) === "function" ? _ref : Object,
		typeof (_ref2 = typeof AgentContext !== "undefined" && AgentContext) === "function" ? _ref2 : Object,
		typeof (_ref3 = typeof DidCommConnectionService !== "undefined" && DidCommConnectionService) === "function" ? _ref3 : Object,
		typeof (_ref4 = typeof EventEmitter !== "undefined" && EventEmitter) === "function" ? _ref4 : Object,
		typeof (_ref5 = typeof DidCommMessagePickupSessionService !== "undefined" && DidCommMessagePickupSessionService) === "function" ? _ref5 : Object,
		typeof (_ref6 = typeof DidCommMessagePickupModuleConfig !== "undefined" && DidCommMessagePickupModuleConfig) === "function" ? _ref6 : Object,
		typeof (_ref7 = typeof Subject !== "undefined" && Subject) === "function" ? _ref7 : Object,
		Object
	])
], DidCommMessagePickupApi);

//#endregion
export { DidCommMessagePickupApi };
//# sourceMappingURL=DidCommMessagePickupApi.mjs.map