"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 WalSnapshot_exports = {};
__export(WalSnapshot_exports, {
  WalSnapshot: () => WalSnapshot
});
module.exports = __toCommonJS(WalSnapshot_exports);
var import_Gzip = require("../../util/Gzip.js");
var import_StringifyTools = require("../StringifyTools.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class WalSnapshot {
  commitId;
  ts;
  data;
  constructor(commitId, ts, data) {
    this.commitId = commitId;
    this.ts = ts;
    this.data = data;
  }
  // --- Programmatic access (synchronous — data is in memory) ---
  /**
   * Get a single value.
   */
  get(contexts, key) {
    const contextKey = contexts.join(".");
    return this.data[contextKey]?.[key];
  }
  /**
   * Get all keys in a context.
   */
  keys(contexts) {
    const contextKey = contexts.join(".");
    return Object.keys(this.data[contextKey] ?? {});
  }
  /**
   * Get all values in a context.
   */
  values(contexts) {
    const contextKey = contexts.join(".");
    return { ...this.data[contextKey] ?? {} };
  }
  /**
   * Get sub-contexts under the given context prefix.
   */
  contexts(contexts) {
    const contextKey = contexts.length ? contexts.join(".") : "";
    const prefix = contextKey.length ? `${contextKey}.` : "";
    const found = /* @__PURE__ */ new Set();
    for (const key of Object.keys(this.data)) {
      if (key.startsWith(prefix)) {
        const sub = key.substring(prefix.length).split(".");
        if (sub.length >= 1 && sub[0].length > 0) {
          found.add(sub[0]);
        }
      }
    }
    return [...found];
  }
  // --- Persistence ---
  /**
   * Write this snapshot to disk (atomic via write+rename).
   */
  async save(dir, options) {
    const compress = options?.compress ?? true;
    const basename = options?.basename ?? "snapshot";
    const snapshot = {
      commitId: this.commitId,
      ts: this.ts,
      data: this.data
    };
    const json = (0, import_StringifyTools.toJson)(snapshot, 2);
    if (compress) {
      const encoded = new TextEncoder().encode(json);
      const tmpFile = dir.file(`${basename}.tmp.json.gz`);
      await tmpFile.write(import_Gzip.Gzip.compress([encoded]));
      await tmpFile.rename(`${basename}.json.gz`);
      const jsonFile = dir.file(`${basename}.json`);
      if (await jsonFile.exists()) {
        await jsonFile.delete();
      }
    } else {
      const tmpFile = dir.file(`${basename}.tmp.json`);
      await tmpFile.write(json);
      await tmpFile.rename(`${basename}.json`);
      const gzFile = dir.file(`${basename}.json.gz`);
      if (await gzFile.exists()) {
        await gzFile.delete();
      }
    }
  }
  /**
   * Load an existing snapshot from disk, auto-detecting the format.
   */
  static async load(dir, options) {
    const basename = options?.basename ?? "snapshot";
    const gzFile = dir.file(`${basename}.json.gz`);
    const jsonFile = dir.file(`${basename}.json`);
    const gzExists = await gzFile.exists();
    const jsonExists = await jsonFile.exists();
    if (!gzExists && !jsonExists) {
      return void 0;
    }
    let text;
    let useGz;
    if (gzExists && jsonExists) {
      const gzMtime = (await gzFile.stat()).mtime;
      const jsonMtime = (await jsonFile.stat()).mtime;
      useGz = gzMtime >= jsonMtime;
    } else {
      useGz = gzExists;
    }
    if (useGz) {
      const chunks = Array();
      for await (const chunk of import_Gzip.Gzip.decompress(gzFile.readBytes())) {
        chunks.push(chunk);
      }
      const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
      const combined = new Uint8Array(totalLength);
      let offset = 0;
      for (const chunk of chunks) {
        combined.set(chunk, offset);
        offset += chunk.length;
      }
      text = new TextDecoder().decode(combined);
    } else {
      text = await jsonFile.readAllText();
    }
    const parsed = (0, import_StringifyTools.fromJson)(text);
    return new WalSnapshot(parsed.commitId, parsed.ts ?? 0, parsed.data);
  }
}
//# sourceMappingURL=WalSnapshot.js.map
