import "server-only";

import { sniffImageType } from "@/lib/media/sniff";

export { sniffImageType };

export class MediaValidationError extends Error {
  constructor(
    message: string,
    readonly status = 400,
  ) {
    super(message);
  }
}

/** Throws when the file is empty, too large, not a supported image, or mislabelled. */
export function validateImage(
  bytes: Uint8Array,
  declaredType: string,
  maxBytes: number,
) {
  if (bytes.byteLength === 0)
    throw new MediaValidationError("The file is empty.");
  if (bytes.byteLength > maxBytes) {
    throw new MediaValidationError(
      `Images can be up to ${Math.round(maxBytes / 1024 / 1024)} MB.`,
      413,
    );
  }
  const sniffed = sniffImageType(bytes);
  if (!sniffed) {
    throw new MediaValidationError(
      "Unsupported file. Upload a JPG, PNG, WebP or AVIF image.",
      415,
    );
  }
  // Browsers report "image/jpg" for some files; treat it as JPEG.
  const declared = declaredType === "image/jpg" ? "image/jpeg" : declaredType;
  if (
    declared &&
    declared !== "application/octet-stream" &&
    declared !== sniffed
  ) {
    throw new MediaValidationError(
      "The file's contents don't match its type.",
      415,
    );
  }
  return { mimeType: sniffed };
}
