import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { init_paths, resolveExtensionsDir, resolveExtensionsLockPath } from "../config/paths.js";
import { mkdir, readFile } from "fs/promises";
import { dirname, join } from "path";
import { existsSync } from "fs";
import { createHash } from "crypto";
//#region src/extensions/lockfile.ts
init_write_file_atomic();
init_logger();
init_paths();
const log = createLogger("ExtensionLockfile");
var ExtensionLockfileManager = class {
	lockfilePath;
	constructor(lockfilePath) {
		this.lockfilePath = lockfilePath || resolveExtensionsLockPath();
	}
	/**
	* Load the lockfile
	*/
	async load() {
		if (!existsSync(this.lockfilePath)) return {
			version: 1,
			lockfileVersion: 1,
			extensions: {}
		};
		try {
			const content = await readFile(this.lockfilePath, "utf-8");
			const data = JSON.parse(content);
			return {
				version: data.version || 1,
				lockfileVersion: data.lockfileVersion || 1,
				extensions: data.extensions || {},
				lastUpdated: data.lastUpdated
			};
		} catch (error) {
			log.warn({ error }, "Failed to load lockfile, starting fresh");
			return {
				version: 1,
				lockfileVersion: 1,
				extensions: {}
			};
		}
	}
	/**
	* Save the lockfile
	*/
	async save(data) {
		data.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
		await mkdir(dirname(this.lockfilePath), { recursive: true });
		await writeTextAtomic(this.lockfilePath, JSON.stringify(data, null, 2));
		log.debug("Lockfile saved");
	}
	/**
	* Add or update an extension entry
	*/
	async upsert(extensionId, entry) {
		const data = await this.load();
		data.extensions[extensionId] = {
			...entry,
			installedAt: (/* @__PURE__ */ new Date()).toISOString()
		};
		await this.save(data);
		log.info({
			extensionId,
			version: entry.version
		}, "Extension locked");
	}
	/**
	* Remove an extension entry
	*/
	async remove(extensionId) {
		const data = await this.load();
		if (data.extensions[extensionId]) {
			delete data.extensions[extensionId];
			await this.save(data);
			log.info({ extensionId }, "Extension removed from lockfile");
		}
	}
	/**
	* Get a specific extension entry
	*/
	async get(extensionId) {
		return (await this.load()).extensions[extensionId] || null;
	}
	/**
	* Check if an extension is locked
	*/
	async has(extensionId) {
		return extensionId in (await this.load()).extensions;
	}
	/**
	* List all locked extensions
	*/
	async list() {
		const data = await this.load();
		return Object.values(data.extensions);
	}
	/**
	* Verify extension integrity
	*/
	async verify(extensionId) {
		if (!await this.get(extensionId)) return {
			valid: false,
			reason: "Extension not in lockfile"
		};
		if (!existsSync(join(resolveExtensionsDir(), extensionId))) return {
			valid: false,
			reason: "Extension directory not found"
		};
		return { valid: true };
	}
	/**
	* Verify all locked extensions
	*/
	async verifyAll() {
		const data = await this.load();
		const results = [];
		for (const extensionId of Object.keys(data.extensions)) results.push({
			extensionId,
			...await this.verify(extensionId)
		});
		return results;
	}
	/**
	* Freeze current state (save with validation)
	*/
	async freeze() {
		const data = await this.load();
		for (const [extensionId] of Object.entries(data.extensions)) if (!existsSync(join(resolveExtensionsDir(), extensionId))) log.warn({ extensionId }, "Extension in lockfile but not installed");
		data.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
		await this.save(data);
		log.info("Lockfile frozen");
		return data;
	}
	/**
	* Generate integrity hash for a file
	*/
	static async generateIntegrity(filePath) {
		const { readFile } = await import("fs/promises");
		const content = await readFile(filePath);
		return "sha512-" + createHash("sha512").update(content).digest("base64");
	}
};
let globalManager;
function getExtensionLockfileManager(lockfilePath) {
	if (!globalManager) globalManager = new ExtensionLockfileManager(lockfilePath);
	return globalManager;
}
function resetExtensionLockfileManager() {
	globalManager = void 0;
}
async function loadExtensionLockfile(lockfilePath) {
	return getExtensionLockfileManager(lockfilePath).load();
}
async function saveExtensionLockfile(data, lockfilePath) {
	return getExtensionLockfileManager(lockfilePath).save(data);
}
//#endregion
export { ExtensionLockfileManager, getExtensionLockfileManager, loadExtensionLockfile, resetExtensionLockfileManager, saveExtensionLockfile };

//# sourceMappingURL=lockfile.js.map