import { createHmac, timingSafeEqual } from "node:crypto";
const secret = "local-fixture-only-storage-signing-secret";
export function mockStorageUrl(
  path: string,
  method: "PUT" | "GET",
  expires: number,
  headers: Record<string, string> = {},
) {
  const value = Buffer.from(
    JSON.stringify({ path, method, expires, headers }),
  ).toString("base64url");
  const signature = createHmac("sha256", secret).update(value).digest("hex");
  return `http://localhost:3101/object?grant=${value}.${signature}`;
}
export function mockStorageGrant(value: string) {
  if (value.length > 4096) throw new Error("Invalid grant");
  const parts = /^([A-Za-z0-9_-]+)\.([a-f0-9]{64})$/.exec(value);
  if (
    !parts ||
    !timingSafeEqual(
      Buffer.from(parts[2], "hex"),
      createHmac("sha256", secret).update(parts[1]).digest(),
    )
  )
    throw new Error("Invalid grant");
  const parsed: unknown = JSON.parse(
    Buffer.from(parts[1], "base64url").toString("utf8"),
  );
  if (!parsed || typeof parsed !== "object") throw new Error("Invalid grant");
  const grant = parsed as {
    path?: unknown;
    method?: unknown;
    expires?: unknown;
    headers?: unknown;
  };
  if (
    typeof grant.path !== "string" ||
    !/^applications\/uploads\/[a-f0-9-]{36}$/.test(grant.path) ||
    !["PUT", "GET"].includes(String(grant.method)) ||
    typeof grant.expires !== "number" ||
    !Number.isFinite(grant.expires) ||
    grant.expires <= Date.now() ||
    !grant.headers ||
    typeof grant.headers !== "object" ||
    Object.values(grant.headers).some((value) => typeof value !== "string")
  )
    throw new Error("Invalid grant");
  return grant as {
    path: string;
    method: "PUT" | "GET";
    expires: number;
    headers: Record<string, string>;
  };
}
