import { logger } from "../../../../logger/index.js";
import { compressToBase64, decompressFromBase64 } from "../../../compress.js";
import { PackageCacheBase } from "./base.js";
import { DateTime } from "luxon";
import upath from "upath";
import cacache from "cacache";
//#region lib/util/cache/package/impl/file.ts
var PackageCacheFile = class PackageCacheFile extends PackageCacheBase {
	static create(cacheDir) {
		const cacheFileName = upath.join(cacheDir, "/renovate/renovate-cache-v1");
		logger.debug(`Initializing Renovate internal cache into ${cacheFileName}`);
		return new PackageCacheFile(cacheFileName);
	}
	cacheFileName;
	constructor(cacheFileName) {
		super();
		this.cacheFileName = cacheFileName;
	}
	getKey(namespace, key) {
		return `${namespace}-${key}`;
	}
	async get(namespace, key) {
		try {
			const raw = (await cacache.get(this.cacheFileName, this.getKey(namespace, key))).data.toString();
			const cached = JSON.parse(raw);
			if (!cached) return;
			const expiry = DateTime.fromISO(cached.expiry);
			if (!expiry.isValid || DateTime.local() >= expiry) {
				await this.rm(namespace, key);
				return;
			}
			logger.trace({
				namespace,
				key
			}, "Returning cached value");
			if (!cached.compress) return cached.value;
			const json = await decompressFromBase64(cached.value);
			return JSON.parse(json);
		} catch {
			logger.trace({
				namespace,
				key
			}, "Cache miss");
		}
	}
	async set(namespace, key, value, hardTtlMinutes) {
		logger.trace({
			namespace,
			key,
			hardTtlMinutes
		}, "Saving cached value");
		const compressedValue = await compressToBase64(JSON.stringify(value));
		const expiry = DateTime.local().plus({ minutes: hardTtlMinutes });
		const payload = JSON.stringify({
			compress: true,
			value: compressedValue,
			expiry
		});
		await cacache.put(this.cacheFileName, this.getKey(namespace, key), payload);
	}
	async destroy() {
		logger.debug("Checking file package cache for expired items");
		let totalCount = 0;
		let deletedCount = 0;
		let errorCount = 0;
		const startTime = Date.now();
		for await (const item of cacache.ls.stream(this.cacheFileName)) try {
			totalCount += 1;
			const cacheEntry = item;
			const entry = await cacache.get(this.cacheFileName, cacheEntry.key);
			let cached;
			try {
				const raw = entry.data.toString();
				cached = JSON.parse(raw);
			} catch {
				logger.debug("Error parsing cached value - deleting");
			}
			if (cached) {
				if (!cached.expiry) continue;
				const expiry = DateTime.fromISO(cached.expiry);
				if (expiry.isValid && DateTime.local() <= expiry) continue;
			}
			await cacache.rm.entry(this.cacheFileName, cacheEntry.key);
			await cacache.rm.content(this.cacheFileName, cacheEntry.integrity);
			deletedCount += 1;
		} catch (err) {
			logger.trace({ err }, "Error cleaning up cache entry");
			errorCount += 1;
		}
		if (errorCount > 0) logger.debug(`Error count cleaning up cache: ${errorCount}`);
		const durationMs = Date.now() - startTime;
		logger.debug(`Deleted ${deletedCount} of ${totalCount} file cached entries in ${durationMs}ms`);
	}
	async rm(namespace, key) {
		logger.trace({
			namespace,
			key
		}, "Removing cache entry");
		await cacache.rm.entry(this.cacheFileName, this.getKey(namespace, key));
	}
};
//#endregion
export { PackageCacheFile };

//# sourceMappingURL=file.js.map