"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var WalCleaner_exports = {};
__export(WalCleaner_exports, {
  WalCleaner: () => WalCleaner
});
module.exports = __toCommonJS(WalCleaner_exports);
var import_WalCommit = require("./WalCommit.js");
var import_WalSnapshot = require("./WalSnapshot.js");
var import_WalTransaction = require("./WalTransaction.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class WalCleaner {
  #walDir;
  #options;
  constructor(walDir, options) {
    this.#walDir = walDir;
    this.#options = options;
  }
  /**
   * Remove WAL segments where all commits are ≤ the snapshot commit ID.
   *
   * A segment is safe to delete only if its segment number is strictly less than the snapshot's segment number (since
   * the snapshot segment itself may have un-snapshotted commits at higher offsets).
   */
  async run(lastSnapshotCommitId) {
    if (!await this.#walDir.exists()) {
      return;
    }
    const toDelete = [];
    for await (const entry of this.#walDir.entries()) {
      if (entry.kind !== "file") continue;
      const segment = (0, import_WalCommit.parseSegmentFilename)(entry.name);
      if (segment === void 0) continue;
      if (segment < lastSnapshotCommitId.segment) {
        toDelete.push({ name: entry.name, segment });
      }
    }
    if (toDelete.length === 0) {
      return;
    }
    if (this.#options?.dir && this.#options.reader) {
      await this.#buildHeadSnapshot(lastSnapshotCommitId);
    }
    toDelete.sort((a, b) => a.segment - b.segment);
    for (const { name } of toDelete) {
      await this.#walDir.file(name).delete();
    }
  }
  /**
   * Replay commits from the segments about to be deleted and save them as a head snapshot.
   */
  async #buildHeadSnapshot(lastSnapshotCommitId) {
    const { dir, compress, reader } = this.#options;
    const existing = await import_WalSnapshot.WalSnapshot.load(dir, { basename: "head" });
    const store = existing?.data ?? {};
    const baseCommitId = existing?.commitId;
    let lastTs = existing?.ts ?? 0;
    let lastAppliedId = baseCommitId;
    for await (const { id, commit } of reader.read(baseCommitId)) {
      if (id.segment >= lastSnapshotCommitId.segment) {
        break;
      }
      (0, import_WalTransaction.applyCommit)(store, commit);
      lastAppliedId = id;
      lastTs = commit.ts || lastTs;
    }
    if (lastAppliedId) {
      const snapshot = new import_WalSnapshot.WalSnapshot(lastAppliedId, lastTs, store);
      await snapshot.save(dir, { compress, basename: "head" });
    }
  }
}
//# sourceMappingURL=WalCleaner.js.map
