import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";

import * as YAML from "yaml";

export function structuredConfigFormatForPath(relativePath) {
  const extension = path.extname(relativePath).toLowerCase();
  if (extension === ".json") return "json";
  if (extension === ".yaml" || extension === ".yml") return "yaml";
  throw new Error(`unsupported structured config extension for ${relativePath}`);
}

export function parseStructuredConfig(text, relativePath = "<structured-config>") {
  const format = structuredConfigFormatForPath(relativePath);
  if (format === "json") return JSON.parse(text);
  return YAML.parse(text);
}

export function stringifyStructuredConfig(value, relativePath = "<structured-config>") {
  const format = structuredConfigFormatForPath(relativePath);
  if (format === "json") return `${JSON.stringify(value, null, 2)}\n`;
  const text = YAML.stringify(value, { indent: 2, lineWidth: 0 });
  return text.endsWith("\n") ? text : `${text}\n`;
}

export async function readStructuredFile(repoRoot, relativePath) {
  const filePath = path.isAbsolute(relativePath) ? relativePath : path.join(repoRoot, relativePath);
  const raw = await readFile(filePath, "utf8");
  return parseStructuredConfig(raw, relativePath);
}

export async function readStructuredFileIfPresent(repoRoot, relativePath, fallback = null) {
  try {
    return await readStructuredFile(repoRoot, relativePath);
  } catch (error) {
    if (error?.code === "ENOENT") return fallback;
    throw error;
  }
}

export async function writeStructuredFile(repoRoot, relativePath, value) {
  const filePath = path.isAbsolute(relativePath) ? relativePath : path.join(repoRoot, relativePath);
  const raw = stringifyStructuredConfig(value, relativePath);
  await writeFile(filePath, raw, "utf8");
}
