import "@js-temporal/polyfill";
import "urlpattern-polyfill";
globalThis.addEventListener = () => {};
import { W as lookupWebFinger, ut as __require } from "./vocab-C5EUmVTj.mjs";
import { i as RouterError, n as traverseCollection, t as lookupObject } from "./lookup-D1kdVIs5.mjs";
import { configure, getConsoleSink, getLogger, reset } from "@logtape/logtape";
import { trace } from "@opentelemetry/api";
//#region src/testing/docloader.ts
const logger = getLogger([
	"fedify",
	"testing",
	"docloader"
]);
/**
* A mock of the document loader.  This does not make any actual HTTP requests
* towards the remote server, but looks up the local fixture files instead.
*
* For instance, `mockDocumentLoader("http://example.com/foo/bar")` will look up
* the file `testing/fixtures/http/example.com/foo/bar` (no suffix) and return
* its content as the response.
*/
async function mockDocumentLoader(resource, _options) {
	const url = new URL(resource);
	if ("navigator" in globalThis && navigator.userAgent === "Cloudflare-Workers") {
		const testUrl = new URL(url);
		testUrl.hostname += ".test";
		const resp = await fetch(testUrl);
		if (resp.ok) {
			const document = await resp.json();
			logger.debug("Successfully fetched fixture {resource}: {status} {statusText}\n{body}", {
				resource,
				status: resp.status,
				statusText: resp.statusText,
				body: document
			});
			return {
				contextUrl: null,
				document,
				documentUrl: resource
			};
		}
		const error = await resp.text();
		logger.error("Failed to fetch fixture {resource}: {error}", {
			resource,
			error
		});
		throw new Error(error);
	}
	const path = `./fixtures/${url.host}${url.pathname}.json`;
	let document;
	try {
		document = (await import(path, { with: { type: "json" } })).default;
	} catch (error) {
		logger.error("Failed to read fixture file {path}: {error}", {
			path,
			error
		});
		throw error;
	}
	return {
		contextUrl: null,
		document,
		documentUrl: resource
	};
}
//#endregion
//#region src/testing/context.ts
function createContext(values) {
	const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, tracerProvider, clone, getNodeInfoUri, getActorUri, getObjectUri, getCollectionUri, getOutboxUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject: lookupObject$1, traverseCollection: traverseCollection$1, lookupNodeInfo, lookupWebFinger: lookupWebFinger$1, sendActivity, routeActivity } = values;
	function throwRouteError() {
		throw new RouterError("Not implemented");
	}
	return {
		federation,
		data,
		origin: url.origin,
		canonicalOrigin: canonicalOrigin ?? url.origin,
		host: url.host,
		hostname: url.hostname,
		documentLoader: documentLoader ?? mockDocumentLoader,
		contextLoader: contextLoader ?? mockDocumentLoader,
		tracerProvider: tracerProvider ?? trace.getTracerProvider(),
		clone: clone ?? ((data) => createContext({
			...values,
			data
		})),
		getNodeInfoUri: getNodeInfoUri ?? throwRouteError,
		getActorUri: getActorUri ?? throwRouteError,
		getObjectUri: getObjectUri ?? throwRouteError,
		getCollectionUri: getCollectionUri ?? throwRouteError,
		getOutboxUri: getOutboxUri ?? throwRouteError,
		getInboxUri: getInboxUri ?? throwRouteError,
		getFollowingUri: getFollowingUri ?? throwRouteError,
		getFollowersUri: getFollowersUri ?? throwRouteError,
		getLikedUri: getLikedUri ?? throwRouteError,
		getFeaturedUri: getFeaturedUri ?? throwRouteError,
		getFeaturedTagsUri: getFeaturedTagsUri ?? throwRouteError,
		parseUri: parseUri ?? ((_uri) => {
			throw new Error("Not implemented");
		}),
		getDocumentLoader: getDocumentLoader ?? ((_params) => {
			throw new Error("Not implemented");
		}),
		getActorKeyPairs: getActorKeyPairs ?? ((_handle) => Promise.resolve([])),
		lookupObject: lookupObject$1 ?? ((uri, options = {}) => {
			return lookupObject(uri, {
				documentLoader: options.documentLoader ?? documentLoader ?? mockDocumentLoader,
				contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader
			});
		}),
		traverseCollection: traverseCollection$1 ?? ((collection, options = {}) => {
			return traverseCollection(collection, {
				documentLoader: options.documentLoader ?? documentLoader ?? mockDocumentLoader,
				contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader
			});
		}),
		lookupNodeInfo: lookupNodeInfo ?? ((_params) => {
			throw new Error("Not implemented");
		}),
		lookupWebFinger: lookupWebFinger$1 ?? ((resource, options = {}) => {
			return lookupWebFinger(resource, options);
		}),
		sendActivity: sendActivity ?? ((_params) => {
			throw new Error("Not implemented");
		}),
		routeActivity: routeActivity ?? ((_params) => {
			throw new Error("Not implemented");
		})
	};
}
function createRequestContext(args) {
	return {
		...createContext(args),
		clone: args.clone ?? ((data) => createRequestContext({
			...args,
			data
		})),
		request: args.request ?? new Request(args.url),
		url: args.url,
		getActor: args.getActor ?? (() => Promise.resolve(null)),
		getObject: args.getObject ?? (() => Promise.resolve(null)),
		getSignedKey: args.getSignedKey ?? (() => Promise.resolve(null)),
		getSignedKeyOwner: args.getSignedKeyOwner ?? (() => Promise.resolve(null)),
		sendActivity: args.sendActivity ?? ((_params) => {
			throw new Error("Not implemented");
		})
	};
}
function createInboxContext(args) {
	return {
		...createContext(args),
		clone: args.clone ?? ((data) => createInboxContext({
			...args,
			data
		})),
		recipient: args.recipient ?? null,
		forwardActivity: args.forwardActivity ?? ((_params) => {
			throw new Error("Not implemented");
		})
	};
}
//#endregion
//#region src/testing/mod.ts
const testDefinitions = [];
function test(name, options, fn) {
	const def = typeof name === "string" ? typeof options === "function" ? {
		name,
		fn: options
	} : {
		name,
		...options,
		fn
	} : name;
	testDefinitions.push(def);
	if ("Deno" in globalThis) {
		const func = def.fn;
		Deno.test({
			...def,
			async fn(t) {
				const records = [];
				await configure({
					sinks: {
						buffer(record) {
							if (record.category.length > 1 && record.category[0] === "logtape" && record.category[1] === "meta") return;
							records.push(record);
						},
						console: getConsoleSink()
					},
					filters: {},
					loggers: [{
						category: [],
						sinks: [Deno.env.get("LOG") === "always" ? "console" : "buffer"]
					}]
				});
				try {
					await func(t);
				} catch (e) {
					const consoleSink = getConsoleSink();
					for (const record of records) consoleSink(record);
					throw e;
				} finally {
					await reset();
				}
			}
		});
	} else if ("Bun" in globalThis) {
		let failed = void 0;
		async function step(defOrNameOrFn, fn) {
			let def;
			if (typeof defOrNameOrFn === "string") def = {
				name: defOrNameOrFn,
				fn
			};
			else if (typeof defOrNameOrFn === "function") def = {
				name: defOrNameOrFn.name,
				fn: defOrNameOrFn
			};
			else def = defOrNameOrFn;
			if (def.ignore) return true;
			try {
				await def.fn({
					name: def.name,
					origin: "",
					step
				});
			} catch (e) {
				failed ??= e;
				return false;
			}
			return true;
		}
		const ctx = {
			name: def.name,
			origin: "",
			step
		};
		async function fn() {
			await def.fn(ctx);
			if (failed) throw failed;
		}
		const bunTest = Bun.jest(caller()).test;
		if (def.ignore) bunTest.skip(def.name, fn);
		else if (def.only) bunTest.only(def.name, fn);
		else bunTest(def.name, fn);
	} else try {
		const { test: nodeTest } = __require("node:test");
		nodeTest(def.name, {
			only: def.only,
			skip: def.ignore
		}, async (t) => {
			await def.fn(intoDenoTestContext(def.name, t));
		});
	} catch {}
}
function intoDenoTestContext(name, ctx) {
	async function step(defOrNameOrFn, fn) {
		let def;
		if (typeof defOrNameOrFn === "string") def = {
			name: defOrNameOrFn,
			fn
		};
		else if (typeof defOrNameOrFn === "function") def = {
			name: defOrNameOrFn.name,
			fn: defOrNameOrFn
		};
		else def = defOrNameOrFn;
		let failed = false;
		await ctx.test(def.name, async (ctx2) => {
			try {
				await def.fn(intoDenoTestContext(def.name, ctx2));
			} catch (e) {
				failed = true;
				throw e;
			}
		});
		return failed;
	}
	return {
		name,
		origin: ctx.filePath ?? "",
		step
	};
}
/** Retrieve caller test file. */
function caller() {
	const Trace = Error;
	const _ = Trace.prepareStackTrace;
	Trace.prepareStackTrace = (_, stack) => stack;
	const { stack } = /* @__PURE__ */ new Error();
	Trace.prepareStackTrace = _;
	return stack[2].getFileName().replaceAll("\\", "/");
}
//#endregion
export { mockDocumentLoader as a, createRequestContext as i, testDefinitions as n, createInboxContext as r, test as t };
