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 { canHandleMessageType, parseMessageType } from "./util/messageType.mjs";
import { DidCommProblemReportMessage } from "./messages/problem-reports/DidCommProblemReportMessage.mjs";
import { DidCommProblemReportError } from "./errors/problem-reports/DidCommProblemReportError.mjs";
import "./errors/problem-reports/index.mjs";
import { DidCommMessageHandlerMiddlewareRunner } from "./handlers/DidCommMessageHandlerMiddleware.mjs";
import "./messages/index.mjs";
import { DidCommProblemReportReason } from "./models/problem-reports/DidCommProblemReportReason.mjs";
import { DidCommOutboundMessageContext } from "./models/DidCommOutboundMessageContext.mjs";
import "./models/index.mjs";
import { DidCommEventTypes } from "./DidCommEvents.mjs";
import { __decorateParam } from "../../../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorateParam.mjs";
import { DidCommMessageSender } from "./DidCommMessageSender.mjs";
import { DidCommMessageHandlerRegistry } from "./DidCommMessageHandlerRegistry.mjs";
import { CredoError, EventEmitter, InjectionSymbols, inject, injectable } from "@credo-ts/core";

//#region ../didcomm/src/DidCommDispatcher.ts
var _ref, _ref2, _ref3;
let DidCommDispatcher = class DidCommDispatcher$1 {
	constructor(messageSender, eventEmitter, messageHandlerRegistry, logger) {
		this.defaultHandlerMiddleware = async (inboundMessageContext, next) => {
			let messageHandler = inboundMessageContext.messageHandler;
			const fallbackMessageHandler = inboundMessageContext.agentContext.dependencyManager.resolve(DidCommMessageHandlerRegistry).fallbackMessageHandler;
			if (!messageHandler && fallbackMessageHandler) messageHandler = {
				supportedMessages: [],
				handle: fallbackMessageHandler
			};
			if (!messageHandler) throw new DidCommProblemReportError(`Error handling message ${inboundMessageContext.message.id} with type ${inboundMessageContext.message.type}. The message type is not supported`, { problemCode: DidCommProblemReportReason.MessageParseFailure });
			const outboundMessage = await messageHandler.handle(inboundMessageContext);
			if (outboundMessage) inboundMessageContext.setResponseMessage(outboundMessage);
			await next();
		};
		this.messageSender = messageSender;
		this.eventEmitter = eventEmitter;
		this.messageHandlerRegistry = messageHandlerRegistry;
		this.logger = logger;
	}
	async dispatch(messageContext) {
		const { agentContext, connection, senderKey, recipientKey, message, encryptedMessage } = messageContext;
		const messageHandler = this.messageHandlerRegistry.getHandlerForMessageType(message.type);
		if (messageHandler) messageContext.setMessageHandler(messageHandler);
		let outboundMessage;
		try {
			const middlewares = [...agentContext.dependencyManager.resolve(DidCommMessageHandlerRegistry).messageHandlerMiddlewares, this.defaultHandlerMiddleware];
			await DidCommMessageHandlerMiddlewareRunner.run(middlewares, messageContext);
			outboundMessage = messageContext.responseMessage;
		} catch (error) {
			const problemReportMessage = error.problemReport;
			if (problemReportMessage instanceof DidCommProblemReportMessage && messageContext.connection) {
				if (canHandleMessageType(DidCommProblemReportMessage, parseMessageType(messageContext.message.type))) throw new CredoError(`Not sending problem report in response to problem report: ${message}`);
				const { protocolUri: problemReportProtocolUri } = parseMessageType(problemReportMessage.type);
				const { protocolUri: inboundProtocolUri } = parseMessageType(messageContext.message.type);
				if (inboundProtocolUri === problemReportProtocolUri) problemReportMessage.setThread({ threadId: message.threadId });
				else problemReportMessage.setThread({ parentThreadId: message.id });
				outboundMessage = new DidCommOutboundMessageContext(problemReportMessage, {
					agentContext,
					connection: messageContext.connection,
					inboundMessageContext: messageContext
				});
			} else {
				this.logger.error(`Error handling message with type ${message.type}`, {
					message: message.toJSON(),
					error,
					senderKey: senderKey?.fingerprint,
					recipientKey: recipientKey?.fingerprint,
					connectionId: connection?.id
				});
				throw error;
			}
		}
		if (outboundMessage) {
			if (!outboundMessage.inboundMessageContext) outboundMessage.inboundMessageContext = messageContext;
			await this.messageSender.sendMessage(outboundMessage);
		}
		this.eventEmitter.emit(agentContext, {
			type: DidCommEventTypes.DidCommMessageProcessed,
			payload: {
				message,
				connection,
				receivedAt: messageContext.receivedAt,
				encryptedMessage
			}
		});
	}
};
DidCommDispatcher = __decorate([
	injectable(),
	__decorateParam(3, inject(InjectionSymbols.Logger)),
	__decorateMetadata("design:paramtypes", [
		typeof (_ref = typeof DidCommMessageSender !== "undefined" && DidCommMessageSender) === "function" ? _ref : Object,
		typeof (_ref2 = typeof EventEmitter !== "undefined" && EventEmitter) === "function" ? _ref2 : Object,
		typeof (_ref3 = typeof DidCommMessageHandlerRegistry !== "undefined" && DidCommMessageHandlerRegistry) === "function" ? _ref3 : Object,
		Object
	])
], DidCommDispatcher);

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