import { parseDiffLines } from "../../diff-lines.js";

export function loadPatchDiffs(files, loadDiff, onLoaded) {
  return Promise.all(files.map(async (file) => {
    const diff = await loadPatchDiff(file, loadDiff);
    onLoaded?.(diff);
    return diff;
  }));
}

async function loadPatchDiff(file, loadDiff) {
  if (file.unavailableReason) {
    return {
      path: file.path,
      unavailableReason: file.unavailableReason,
      ...changeStats(file, []),
      lines: []
    };
  }
  if (typeof file.diff === "string") {
    const lines = parseDiffLines(file.diff);
    return {
      path: file.path,
      ...changeStats(file, lines),
      lines
    };
  }
  try {
    const result = await loadDiff(file.path);
    const lines = parseDiffLines(result.diff ?? "");
    return {
      path: file.path,
      unavailableReason: result.unavailableReason,
      ...changeStats(file, lines),
      lines
    };
  } catch (error) {
    if (error?.message === "changed_file_not_found") {
      return { path: file.path, unavailableReason: "changed_file_not_found", lines: [] };
    }
    return { path: file.path, error: "changes_diff_failed", lines: [] };
  }
}

function changeStats(file, lines) {
  const additions = lines.filter((line) => line.kind === "addition").length;
  const deletions = lines.filter((line) => line.kind === "deletion").length;
  return {
    additions: additions || numericCount(file.additions),
    deletions: deletions || numericCount(file.deletions)
  };
}

function numericCount(value) {
  return Number.isFinite(value) ? value : 0;
}
