"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 StorageMigration_exports = {};
__export(StorageMigration_exports, {
  StorageMigration: () => StorageMigration
});
module.exports = __toCommonJS(StorageMigration_exports);
var import_Logger = require("#log/Logger.js");
var import_MatterError = require("#MatterError.js");
var import_StorageDriver = require("./StorageDriver.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const logger = new import_Logger.Logger("StorageMigrator");
var StorageMigration;
((StorageMigration2) => {
  async function migrate(source, target) {
    const strategy = resolveStrategy(source.type, target.type);
    const result = {
      success: true,
      migratedCount: 0,
      skippedCount: 0,
      otherTypeKeysSkipped: 0,
      skippedItems: []
    };
    await migrateContext({ source, target, strategy, contexts: [], result });
    if (result.otherTypeKeysSkipped > 0) {
      logger.info(`[migrate] Skipped ${result.otherTypeKeysSkipped} keys not matching target type`);
    }
    result.success = result.skippedCount === 0;
    return result;
  }
  StorageMigration2.migrate = migrate;
  function resultToLog(result) {
    const timestamp = (/* @__PURE__ */ new Date()).toISOString();
    let logContent = `
    # Migration Log
    - Timestamp: ${timestamp}
    - Success: ${result.success}
    - Migrated: ${result.migratedCount}
    - Skipped: ${result.skippedCount}
    `.replace(/^\s+/gm, "");
    if (result.skippedCount > 0 && result.skippedItems.length > 0) {
      logContent += `
## Skipped Items
`;
      for (const item of result.skippedItems) {
        logContent += `- ${buildContextKeyLog(item.contexts, item.key)}: ${item.error}
`;
      }
    }
    return logContent;
  }
  StorageMigration2.resultToLog = resultToLog;
})(StorageMigration || (StorageMigration = {}));
function resolveStrategy(sourceType, targetType) {
  if (sourceType === targetType) {
    return sourceType;
  }
  if (sourceType === "kv" && targetType === "blob") {
    return "kv-to-blob";
  }
  throw new import_StorageDriver.StorageError(`Cannot migrate from "${sourceType}" storage to "${targetType}" storage`);
}
async function migrateContext(args) {
  const { source, target, strategy, contexts, result } = args;
  const keys = await source.keys(contexts);
  for (const key of keys) {
    try {
      switch (strategy) {
        case "kv":
          await migrateKvKey(source, target, contexts, key, result);
          break;
        case "blob":
          await migrateBlobKey(
            source,
            target,
            contexts,
            key,
            result
          );
          break;
        case "kv-to-blob":
          await extractBlobFromKv(
            source,
            target,
            contexts,
            key,
            result
          );
          break;
      }
    } catch (err) {
      result.skippedCount += 1;
      result.skippedItems.push({
        contexts,
        key,
        error: err instanceof Error ? err.message : String(err)
      });
      logger.warn(`[migrate] Skipped '${buildContextKeyLog(contexts, key)}' entity: ${err}`);
    }
  }
  const subContexts = await source.contexts(contexts);
  const promises = [];
  subContexts.forEach((subCon) => {
    promises.push(
      migrateContext({
        ...args,
        contexts: [...contexts, subCon]
      })
    );
  });
  await import_MatterError.MatterAggregateError.allSettled(promises, "[migrate] Error migrating sub-contexts!");
}
async function migrateKvKey(source, target, contexts, key, result) {
  const value = await source.get(contexts, key);
  if (value === void 0) {
    result.otherTypeKeysSkipped++;
    return;
  }
  await target.set(contexts, key, value);
  result.migratedCount++;
}
async function migrateBlobKey(source, target, contexts, key, result) {
  const blob = await source.openBlob(contexts, key);
  if (blob.size === 0) {
    return;
  }
  await target.writeBlobFromStream(contexts, key, blob.stream());
  result.migratedCount++;
}
async function extractBlobFromKv(source, target, contexts, key, result) {
  const value = await source.get(contexts, key);
  if (value !== void 0) {
    result.otherTypeKeysSkipped++;
    return;
  }
  if (!isLegacyBlobSource(source)) {
    result.otherTypeKeysSkipped++;
    return;
  }
  await migrateBlobKey(source, target, contexts, key, result);
}
function isLegacyBlobSource(driver) {
  return "openBlob" in driver && typeof driver.openBlob === "function";
}
function buildContextKeyLog(contexts, key) {
  return `${contexts.join(".")}$${key}`;
}
//# sourceMappingURL=StorageMigration.js.map
