import fs from "node:fs";
import { z } from "zod";
import { toErrorMessage } from "../../util";

export type ParseJsonResult<T> = { ok: true; data: T } | { ok: false; error: string };

export function parseJsonWith<T>(
  raw: string,
  schema: z.ZodType<T>,
  label: string,
): ParseJsonResult<T> {
  let parsed: unknown;
  try {
    parsed = JSON.parse(raw);
  } catch (err) {
    return { ok: false, error: `Failed to parse ${label}: ${toErrorMessage(err)}` };
  }
  const result = schema.safeParse(parsed);
  if (!result.success) {
    return { ok: false, error: `Invalid ${label}:\n${z.prettifyError(result.error)}` };
  }
  return { ok: true, data: result.data };
}

export function readJsonFile<T>(
  filePath: string,
  schema: z.ZodType<T>,
  label = filePath,
): ParseJsonResult<T> {
  let raw: string;
  try {
    raw = fs.readFileSync(filePath, "utf-8");
  } catch (err) {
    return { ok: false, error: `Failed to read ${label}: ${toErrorMessage(err)}` };
  }
  return parseJsonWith(raw, schema, label);
}
