import { mkdir, readFile, writeFile, rename, unlink } from "node:fs/promises";
import { dirname, resolve, sep } from "node:path";
import { randomUUID } from "node:crypto";
export const storageRoot = () => {
  const root = resolve(process.env.STORAGE_DIR || "data/private-files");
  if (root === resolve("public") || root.startsWith(resolve("public") + sep))
    throw new Error("storage_must_be_private");
  return root;
};
export function storagePath(key: string) {
  const root = storageRoot(),
    target = resolve(root, key);
  if (!key || target === root || !target.startsWith(root + sep))
    throw new Error("invalid_storage_key");
  return target;
}
export const FILES = {
  async put(
    key: string,
    data: ArrayBuffer | ArrayBufferView,
    _metadata?: unknown,
  ) {
    const target = storagePath(key);
    await mkdir(dirname(target), { recursive: true, mode: 0o700 });
    const bytes = ArrayBuffer.isView(data)
      ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
      : new Uint8Array(data);
    const temp = target + "." + randomUUID() + ".tmp";
    try {
      await writeFile(temp, bytes, { mode: 0o600, flag: "wx" });
      await rename(temp, target);
    } finally {
      await unlink(temp).catch(() => {});
    }
  },
  async get(key: string) {
    try {
      return { body: new Uint8Array(await readFile(storagePath(key))) };
    } catch (error) {
      if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
      throw error;
    }
  },
  async delete(key: string) {
    try {
      await unlink(storagePath(key));
    } catch (error) {
      if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
    }
  },
};
