"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const async = require("../../../../base/common/async.js");
const functional = require("../../../../base/common/functional.js");
const map = require("../../../../base/common/map.js");
const range = require("../../../common/core/range.js");
const codelens = require("./codelens.js");
const extensions = require("../../../../platform/instantiation/common/extensions.js");
const instantiation = require("../../../../platform/instantiation/common/instantiation.js");
const storage = require("../../../../platform/storage/common/storage.js");
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
const ICodeLensCache = instantiation.createDecorator("ICodeLensCache");
class CacheItem {
  constructor(lineCount, data) {
    this.lineCount = lineCount;
    this.data = data;
  }
}
exports.CodeLensCache = class CodeLensCache {
  constructor(storageService) {
    this._fakeProvider = new class {
      provideCodeLenses() {
        throw new Error("not supported");
      }
    }();
    this._cache = new map.LRUCache(20, 0.75);
    const oldkey = "codelens/cache";
    async.runWhenIdle(() => storageService.remove(
      oldkey,
      1
      /* WORKSPACE */
    ));
    const key = "codelens/cache2";
    const raw = storageService.get(key, 1, "{}");
    this._deserialize(raw);
    functional.once(storageService.onWillSaveState)((e) => {
      if (e.reason === storage.WillSaveStateReason.SHUTDOWN) {
        storageService.store(
          key,
          this._serialize(),
          1,
          1
          /* MACHINE */
        );
      }
    });
  }
  put(model, data) {
    const copyItems = data.lenses.map((item2) => {
      var _a;
      return {
        range: item2.symbol.range,
        command: item2.symbol.command && { id: "", title: (_a = item2.symbol.command) === null || _a === void 0 ? void 0 : _a.title }
      };
    });
    const copyModel = new codelens.CodeLensModel();
    copyModel.add({ lenses: copyItems, dispose: () => {
    } }, this._fakeProvider);
    const item = new CacheItem(model.getLineCount(), copyModel);
    this._cache.set(model.uri.toString(), item);
  }
  get(model) {
    const item = this._cache.get(model.uri.toString());
    return item && item.lineCount === model.getLineCount() ? item.data : void 0;
  }
  delete(model) {
    this._cache.delete(model.uri.toString());
  }
  // --- persistence
  _serialize() {
    const data = /* @__PURE__ */ Object.create(null);
    for (const [key, value] of this._cache) {
      const lines = /* @__PURE__ */ new Set();
      for (const d of value.data.lenses) {
        lines.add(d.symbol.range.startLineNumber);
      }
      data[key] = {
        lineCount: value.lineCount,
        lines: [...lines.values()]
      };
    }
    return JSON.stringify(data);
  }
  _deserialize(raw) {
    try {
      const data = JSON.parse(raw);
      for (const key in data) {
        const element = data[key];
        const lenses = [];
        for (const line of element.lines) {
          lenses.push({ range: new range.Range(line, 1, line, 11) });
        }
        const model = new codelens.CodeLensModel();
        model.add({ lenses, dispose() {
        } }, this._fakeProvider);
        this._cache.set(key, new CacheItem(element.lineCount, model));
      }
    } catch (_a) {
    }
  }
};
exports.CodeLensCache = __decorate([
  __param(0, storage.IStorageService)
], exports.CodeLensCache);
extensions.registerSingleton(ICodeLensCache, exports.CodeLensCache);
exports.ICodeLensCache = ICodeLensCache;
