
      import { Temporal } from "@js-temporal/polyfill";
      import { URLPattern } from "urlpattern-polyfill";
      globalThis.addEventListener = () => {};
    
import { deno_default } from "./type-BSR-vRXo.js";
import { doubleKnock } from "./http-CCydyMoV.js";
import { getLogger } from "@logtape/logtape";
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";

//#region src/federation/send.ts
/**
* Extracts the inbox URLs from recipients.
* @param parameters The parameters to extract the inboxes.
*                   See also {@link ExtractInboxesParameters}.
* @returns The inboxes as a map of inbox URL to actor URIs.
*/
function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
	const inboxes = {};
	for (const recipient of recipients) {
		let inbox;
		let sharedInbox = false;
		if (preferSharedInbox && recipient.endpoints?.sharedInbox != null) {
			inbox = recipient.endpoints.sharedInbox;
			sharedInbox = true;
		} else inbox = recipient.inboxId;
		if (inbox != null && recipient.id != null) {
			if (excludeBaseUris != null && excludeBaseUris.some((u) => u.origin === inbox?.origin)) continue;
			inboxes[inbox.href] ??= {
				actorIds: /* @__PURE__ */ new Set(),
				sharedInbox
			};
			inboxes[inbox.href].actorIds.add(recipient.id.href);
		}
	}
	return inboxes;
}
/**
* Sends an {@link Activity} to an inbox.
*
* @param parameters The parameters for sending the activity.
*                   See also {@link SendActivityParameters}.
* @throws {Error} If the activity fails to send.
*/
function sendActivity(options) {
	const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
	const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
	return tracer.startActiveSpan("activitypub.send_activity", {
		kind: SpanKind.CLIENT,
		attributes: { "activitypub.shared_inbox": options.sharedInbox ?? false }
	}, async (span) => {
		if (options.activityId != null) span.setAttribute("activitypub.activity.id", options.activityId);
		if (options.activityType != null) span.setAttribute("activitypub.activity.type", options.activityType);
		try {
			await sendActivityInternal({
				...options,
				tracerProvider
			});
		} catch (e) {
			span.setStatus({
				code: SpanStatusCode.ERROR,
				message: String(e)
			});
			throw e;
		} finally {
			span.end();
		}
	});
}
async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }) {
	const logger = getLogger([
		"fedify",
		"federation",
		"outbox"
	]);
	headers = new Headers(headers);
	headers.set("Content-Type", "application/activity+json");
	const request = new Request(inbox, {
		method: "POST",
		headers,
		body: JSON.stringify(activity)
	});
	let rsaKey = null;
	for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
		rsaKey = key;
		break;
	}
	if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}.  The request will be sent without a signature.  In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
		inbox: inbox.href,
		keys: keys.map((pair) => ({
			keyId: pair.keyId.href,
			privateKey: pair.privateKey
		}))
	});
	let response;
	try {
		response = rsaKey == null ? await fetch(request) : await doubleKnock(request, rsaKey, {
			tracerProvider,
			specDeterminer
		});
	} catch (error) {
		logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
			activityId,
			inbox: inbox.href,
			error
		});
		throw error;
	}
	if (!response.ok) {
		let error;
		try {
			error = await response.text();
		} catch (_) {
			error = "";
		}
		logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
			activityId,
			inbox: inbox.href,
			status: response.status,
			statusText: response.statusText,
			error
		});
		throw new Error(`Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`);
	}
}

//#endregion
export { extractInboxes, sendActivity };