import { error } from "@sveltejs/kit";
import { createBobbinClient } from "$lib/api/client";
import { resolveMiniDoc } from "$lib/api/identity";
import { blobRawUrl } from "$lib/api/knot";
import { toHttpError } from "$lib/api/load";
import { resolveRepoByName } from "$lib/api/repo";
import { getConfig } from "$lib/server/config";
import type { RequestHandler } from "./$types";

// redirecting instead of proxying keeps repo content off our own origin, same
// as camo and avatar
export const GET: RequestHandler = async (event) => {
	const identifier = decodeURIComponent(event.params.handle);
	const name = decodeURIComponent(event.params.repo);
	const { ref, path } = event.params;

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

	const { bobbinUrl } = getConfig();
	const ctx = createBobbinClient({ serviceUrl: 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`);

	// a branch points at a new commit after every push, so this cannot cache
	return new Response(null, {
		status: 302,
		headers: {
			location: blobRawUrl(bobbinUrl, { repo: view.uri, ref, path }),
			"cache-control": "public, no-cache"
		}
	});
};
