
      import { Temporal } from "@js-temporal/polyfill";
      import { URLPattern } from "urlpattern-polyfill";
      globalThis.addEventListener = () => {};
    
import { Activity, Note, Person } from "../type-BSR-vRXo.js";
import { assertEquals } from "../assert_equals-DSbWqCm3.js";
import "../assert-MZs1qjMx.js";
import "../assert_instance_of-DHz7EHNU.js";
import { MemoryKvStore } from "../kv-CRZrzyXm.js";
import "../lookup-q8DeFAjR.js";
import "../inbox-DH8TXk1f.js";
import { createFederationBuilder } from "../builder-B6AupxqD.js";
import { test } from "../testing-Cqwzq9nj.js";
import { assertExists } from "../std__assert-X-_kMxKM.js";
import "../assert_rejects-DiIiJbZn.js";
import "../assert_is_error-BPGph1Jx.js";
import "../assert_not_equals-f3m3epl3.js";
import { assertThrows } from "../assert_throws-BOO88avQ.js";

//#region src/federation/builder.test.ts
test("FederationBuilder", async (t) => {
	await t.step("should build a Federation object with registered components", async () => {
		const builder = createFederationBuilder();
		const kv = new MemoryKvStore();
		const actorDispatcher = (_ctx, _identifier) => {
			return null;
		};
		builder.setActorDispatcher("/users/{identifier}", actorDispatcher);
		const inboxListener = (_ctx, _activity) => {};
		const listeners = builder.setInboxListeners("/users/{identifier}/inbox");
		listeners.on(Activity, inboxListener);
		const objectDispatcher = (_ctx, _values) => {
			return null;
		};
		builder.setObjectDispatcher(Note, "/notes/{id}", objectDispatcher);
		const nodeInfo = {
			version: "2.1",
			software: {
				name: "test",
				version: "1.0.0"
			},
			protocols: ["activitypub"],
			services: {
				inbound: [],
				outbound: []
			},
			openRegistrations: false,
			usage: {
				users: {},
				localPosts: 0,
				localComments: 0
			},
			metadata: {}
		};
		const nodeInfoDispatcher = (_ctx) => nodeInfo;
		builder.setNodeInfoDispatcher("/nodeinfo", nodeInfoDispatcher);
		const federation = await builder.build({ kv });
		assertExists(federation);
		const impl = federation;
		assertEquals(impl.router.route("/.well-known/webfinger")?.name, "webfinger");
		assertEquals(impl.router.route("/users/test123")?.name, "actor");
		assertEquals(impl.router.route("/users/test123/inbox")?.name, "inbox");
		assertEquals(impl.router.route("/notes/456")?.name, `object:${Note.typeId.href}`);
		assertEquals(impl.router.route("/nodeinfo")?.name, "nodeInfo");
		const actorCallbacksDispatcher = impl.actorCallbacks?.dispatcher;
		assertExists(actorCallbacksDispatcher);
		const inboxListeners = impl.inboxListeners;
		assertExists(inboxListeners);
		assertExists(impl.objectCallbacks[Note.typeId.href]);
		assertExists(impl.nodeInfoDispatcher);
		const notePaths = impl.router.build(`object:${Note.typeId.href}`, { id: "123" });
		assertEquals(notePaths, "/notes/123");
		assertEquals(impl.router.build("actor", { identifier: "user1" }), "/users/user1");
		assertEquals(impl.router.build("inbox", { identifier: "user1" }), "/users/user1/inbox");
		await builder.build({ kv });
	});
	await t.step("should build with default options", async () => {
		const builder = createFederationBuilder();
		const kv = new MemoryKvStore();
		const federation = await builder.build({ kv });
		assertExists(federation);
		const impl = federation;
		assertEquals(impl.kv, kv);
	});
	await t.step("should pass build options correctly", async () => {
		const builder = createFederationBuilder();
		const kv = new MemoryKvStore();
		const federation = await builder.build({
			kv,
			kvPrefixes: { activityIdempotence: ["custom", "idem"] },
			allowPrivateAddress: true,
			trailingSlashInsensitive: true,
			origin: "https://example.com"
		});
		assertExists(federation);
		const impl = federation;
		assertEquals(impl.kv, kv);
		assertEquals(impl.kvPrefixes.activityIdempotence, ["custom", "idem"]);
		assertEquals(impl.allowPrivateAddress, true);
		assertEquals(impl.router.trailingSlashInsensitive, true);
		assertEquals(impl.origin?.webOrigin, "https://example.com");
	});
	await t.step("should handle firstKnock option", async () => {
		const builder = createFederationBuilder();
		const kv = new MemoryKvStore();
		const federationDefault = await builder.build({ kv });
		assertExists(federationDefault);
		const implDefault = federationDefault;
		assertEquals(implDefault.firstKnock, void 0);
		const federationCustom = await builder.build({
			kv,
			firstKnock: "draft-cavage-http-signatures-12"
		});
		assertExists(federationCustom);
		const implCustom = federationCustom;
		assertEquals(implCustom.firstKnock, "draft-cavage-http-signatures-12");
		const federationRfc = await builder.build({
			kv,
			firstKnock: "rfc9421"
		});
		assertExists(federationRfc);
		const implRfc = federationRfc;
		assertEquals(implRfc.firstKnock, "rfc9421");
	});
	await t.step("should register multiple object dispatchers and verify them", async () => {
		const builder = createFederationBuilder();
		const kv = new MemoryKvStore();
		const noteDispatcher = (_ctx, _values) => {
			return null;
		};
		const personDispatcher = (_ctx, _values) => {
			return null;
		};
		builder.setObjectDispatcher(Note, "/notes/{id}", noteDispatcher);
		builder.setObjectDispatcher(Person, "/people/{id}", personDispatcher);
		const federation = await builder.build({ kv });
		const impl = federation;
		assertExists(impl.objectCallbacks[Note.typeId.href]);
		assertExists(impl.objectCallbacks[Person.typeId.href]);
		const notePath = impl.router.build(`object:${Note.typeId.href}`, { id: "123" });
		assertEquals(notePath, "/notes/123");
		const personPath = impl.router.build(`object:${Person.typeId.href}`, { id: "456" });
		assertEquals(personPath, "/people/456");
		const noteRoute = impl.router.route("/notes/789");
		assertEquals(noteRoute?.name, `object:${Note.typeId.href}`);
		assertEquals(noteRoute?.values.id, "789");
		const personRoute = impl.router.route("/people/abc");
		assertEquals(personRoute?.name, `object:${Person.typeId.href}`);
		assertEquals(personRoute?.values.id, "abc");
	});
	await t.step("should handle symbol names uniquely in custom collection dispatchers", () => {
		const builder = createFederationBuilder();
		const unnamedSymbol1 = Symbol();
		const unnamedSymbol2 = Symbol();
		const namedSymbol1 = Symbol.for("");
		const namedSymbol2 = Symbol.for("");
		const strId = String(unnamedSymbol1);
		const dispatcher = (_ctx, _params) => ({ items: [] });
		builder.setCollectionDispatcher(unnamedSymbol1, Note, "/unnamed-symbol1/{id}", dispatcher);
		assertThrows(() => {
			builder.setCollectionDispatcher(unnamedSymbol1, Note, "/unnamed-symbol1-duplicate/{id}", dispatcher);
		}, Error, "Collection dispatcher for Symbol() already set.");
		builder.setCollectionDispatcher(unnamedSymbol2, Note, "/unnamed-symbol2/{id}", dispatcher);
		builder.setCollectionDispatcher(namedSymbol1, Note, "/named-symbol/{id}", dispatcher);
		assertThrows(() => {
			builder.setCollectionDispatcher(namedSymbol2, Note, "/named-symbol/{id}", dispatcher);
		});
		builder.setCollectionDispatcher(strId, Note, "/string-id/{id}", dispatcher);
	});
});

//#endregion