import { assert } from "../../../shared/src/asserts.js";
import { diff as diff$1 } from "../btree/diff.js";
import { BTreeRead, allEntriesAsDiff } from "../btree/read.js";
import { commitFromHash } from "../db/commit.js";
import { readIndexesForRead } from "../db/read.js";
class DiffsMap extends Map {
  set(key, value) {
    if (value.length === 0) {
      return this;
    }
    return super.set(key, value);
  }
}
async function diff(oldHash, newHash, read, diffConfig, formatVersion) {
  const [oldCommit, newCommit] = await Promise.all([
    commitFromHash(oldHash, read),
    commitFromHash(newHash, read)
  ]);
  return diffCommits(oldCommit, newCommit, read, diffConfig, formatVersion);
}
async function diffCommits(oldCommit, newCommit, read, diffConfig, formatVersion) {
  const diffsMap = new DiffsMap();
  if (!diffConfig.shouldComputeDiffs()) {
    return diffsMap;
  }
  const oldMap = new BTreeRead(read, formatVersion, oldCommit.valueHash);
  const newMap = new BTreeRead(read, formatVersion, newCommit.valueHash);
  const valueDiff = await diff$1(oldMap, newMap);
  diffsMap.set("", valueDiff);
  await addDiffsForIndexes(
    oldCommit,
    newCommit,
    read,
    diffsMap,
    diffConfig,
    formatVersion
  );
  return diffsMap;
}
async function addDiffsForIndexes(mainCommit, syncCommit, read, diffsMap, diffConfig, formatVersion) {
  const oldIndexes = readIndexesForRead(mainCommit, read, formatVersion);
  const newIndexes = readIndexesForRead(syncCommit, read, formatVersion);
  for (const [oldIndexName, oldIndex] of oldIndexes) {
    if (!diffConfig.shouldComputeDiffsForIndex(oldIndexName)) {
      continue;
    }
    const newIndex = newIndexes.get(oldIndexName);
    if (newIndex !== void 0) {
      assert(newIndex !== oldIndex);
      const diffs = await diff$1(oldIndex.map, newIndex.map);
      newIndexes.delete(oldIndexName);
      diffsMap.set(oldIndexName, diffs);
    } else {
      const diffs = await allEntriesAsDiff(oldIndex.map, "del");
      diffsMap.set(oldIndexName, diffs);
    }
  }
  for (const [newIndexName, newIndex] of newIndexes) {
    if (!diffConfig.shouldComputeDiffsForIndex(newIndexName)) {
      continue;
    }
    const diffs = await allEntriesAsDiff(newIndex.map, "add");
    diffsMap.set(newIndexName, diffs);
  }
}
export {
  DiffsMap,
  addDiffsForIndexes,
  diff,
  diffCommits
};
//# sourceMappingURL=diff.js.map
