import { error } from "@sveltejs/kit";
import { createBobbinClient, type BobbinContext } from "$lib/api/client";
import { gitTarget, type GitTarget } from "$lib/api/gitclient";
import { resolveMiniDoc, type MiniDoc } from "$lib/api/identity";
import { toHttpError } from "$lib/api/load";
import type { RecordView, RepoRecord } from "$lib/api/records";
import { resolveRepoByName } from "$lib/api/repo";
import { getConfig } from "$lib/server/config";

export interface ResolvedRepo {
	ctx: BobbinContext;
	git: GitTarget;
	doc: MiniDoc;
	view: RecordView<RepoRecord>;
}

// the handle/repo preamble shared by the raw-content routes, params arrive
// already decoded
export const resolveRepoFromParams = async (event: {
	params: { handle?: string; repo?: string };
	fetch: typeof fetch;
}): Promise<ResolvedRepo> => {
	const identifier = event.params.handle ?? "";
	const name = event.params.repo ?? "";

	// rejects bare words, unrelated paths must 404 instead of resolving as actors
	if (!identifier.startsWith("did:") && !identifier.includes(".")) {
		error(404, "Not found");
	}

	const config = getConfig();
	const ctx = createBobbinClient({ serviceUrl: config.bobbinUrl, fetch: event.fetch });

	const doc = await resolveMiniDoc(ctx, identifier).catch((cause) =>
		toHttpError(cause, "Could not resolve user")
	);
	const view = await resolveRepoByName(ctx, doc.did, name).catch((cause) =>
		toHttpError(cause, "Could not load repository")
	);
	if (!view) error(404, `${doc.handle}/${name} does not exist`);

	const git = gitTarget(config, { uri: view.uri, repoDid: view.value.repoDid }, event.fetch);

	return { ctx, git, doc, view };
};
