const require_rolldown_runtime = require('../../../../../_virtual/rolldown_runtime.js');
const require_decorateMetadata = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateMetadata.js');
const require_decorate = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js');
const require_DidCommOutboundMessageContext = require('../../models/DidCommOutboundMessageContext.js');
require('../../models/index.js');
const require_index$1 = require('../../../../../node_modules/.pnpm/rxjs@7.8.2/node_modules/rxjs/dist/cjs/index.js');
const require_DidCommModuleConfig = require('../../DidCommModuleConfig.js');
const require_decorateParam = require('../../../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateParam.js');
const require_DidCommConnectionService = require('../connections/services/DidCommConnectionService.js');
const require_DidCommMessageSender = require('../../DidCommMessageSender.js');
require('../connections/services/index.js');
const require_DidCommMessagePickupEvents = require('./DidCommMessagePickupEvents.js');
const require_DidCommMessagePickupModuleConfig = require('./DidCommMessagePickupModuleConfig.js');
const require_DidCommMessagePickupSessionService = require('./services/DidCommMessagePickupSessionService.js');
let __credo_ts_core = require("@credo-ts/core");
__credo_ts_core = require_rolldown_runtime.__toESM(__credo_ts_core);

//#region ../didcomm/src/modules/message-pickup/DidCommMessagePickupApi.ts
var import_cjs = /* @__PURE__ */ require_rolldown_runtime.__toESM(require_index$1.require_cjs());
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 __credo_ts_core.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(require_DidCommModuleConfig.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 __credo_ts_core.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 require_DidCommOutboundMessageContext.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 __credo_ts_core.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 require_DidCommOutboundMessageContext.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 require_DidCommOutboundMessageContext.DidCommOutboundMessageContext(message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		});
		const replaySubject = new import_cjs.ReplaySubject(1);
		if (options.awaitCompletion) this.eventEmitter.observable(require_DidCommMessagePickupEvents.DidCommMessagePickupEventTypes.MessagePickupCompleted).pipe((0, import_cjs.takeUntil)(this.stop$), (0, import_cjs.filter)((e) => e.payload.connection.id === connectionRecord.id), (0, import_cjs.first)(), (0, import_cjs.timeout)({
			first: options.awaitCompletionTimeoutMs ?? 1e4,
			meta: "DidCommMessagePickupApi.pickupMessages"
		})).subscribe(replaySubject);
		await this.messageSender.sendMessage(outboundMessageContext, { transportPriority: { schemes: ["wss", "ws"] } });
		if (options.awaitCompletion) await (0, import_cjs.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 require_DidCommOutboundMessageContext.DidCommOutboundMessageContext(message, {
			agentContext: this.agentContext,
			connection: connectionRecord
		}), { transportPriority: {
			schemes: ["wss", "ws"],
			restrictive: options.liveDelivery
		} });
	}
};
DidCommMessagePickupApi = require_decorate.__decorate([
	(0, __credo_ts_core.injectable)(),
	require_decorateParam.__decorateParam(6, (0, __credo_ts_core.inject)(__credo_ts_core.InjectionSymbols.Stop$)),
	require_decorateParam.__decorateParam(7, (0, __credo_ts_core.inject)(__credo_ts_core.InjectionSymbols.Logger)),
	require_decorateMetadata.__decorateMetadata("design:paramtypes", [
		typeof (_ref = typeof require_DidCommMessageSender.DidCommMessageSender !== "undefined" && require_DidCommMessageSender.DidCommMessageSender) === "function" ? _ref : Object,
		typeof (_ref2 = typeof __credo_ts_core.AgentContext !== "undefined" && __credo_ts_core.AgentContext) === "function" ? _ref2 : Object,
		typeof (_ref3 = typeof require_DidCommConnectionService.DidCommConnectionService !== "undefined" && require_DidCommConnectionService.DidCommConnectionService) === "function" ? _ref3 : Object,
		typeof (_ref4 = typeof __credo_ts_core.EventEmitter !== "undefined" && __credo_ts_core.EventEmitter) === "function" ? _ref4 : Object,
		typeof (_ref5 = typeof require_DidCommMessagePickupSessionService.DidCommMessagePickupSessionService !== "undefined" && require_DidCommMessagePickupSessionService.DidCommMessagePickupSessionService) === "function" ? _ref5 : Object,
		typeof (_ref6 = typeof require_DidCommMessagePickupModuleConfig.DidCommMessagePickupModuleConfig !== "undefined" && require_DidCommMessagePickupModuleConfig.DidCommMessagePickupModuleConfig) === "function" ? _ref6 : Object,
		typeof (_ref7 = typeof import_cjs.Subject !== "undefined" && import_cjs.Subject) === "function" ? _ref7 : Object,
		Object
	])
], DidCommMessagePickupApi);

//#endregion
Object.defineProperty(exports, 'DidCommMessagePickupApi', {
  enumerable: true,
  get: function () {
    return DidCommMessagePickupApi;
  }
});