const require_rolldown_runtime = require('../../../../_virtual/rolldown_runtime.cjs');
const require_logger = require('../../../config/dist/esm/logger.cjs');
const require_ESMxCJSHelpers = require('../../../config/dist/esm/utils/ESMxCJSHelpers.cjs');
const require_getConfiguration = require('../../../config/dist/esm/configFile/getConfiguration.cjs');
const require_parallelize = require('./chokidar/dist/esm/utils/parallelize.cjs');
const require_writeContentDeclaration = require('./chokidar/dist/esm/writeContentDeclaration/writeContentDeclaration.cjs');
const require_proxy = require('./api/dist/esm/proxy.cjs');
const require_checkAccess = require('./utils/checkAccess.cjs');
const require_pullLog = require('./push/pullLog.cjs');
let node_path = require("node:path");
let node_fs = require("node:fs");

//#region ../@intlayer/cli/dist/esm/pull.mjs
/**
* Fetch distant dictionaries and write them locally,
* with progress indicators and concurrency control.
*/
const pull = async (options) => {
	const appLogger = require_logger.getAppLogger(options?.configOptions?.override);
	try {
		const config = require_getConfiguration.getConfiguration(options?.configOptions);
		if (!await require_checkAccess.checkCMSAuth(config)) return;
		const intlayerAPI = require_proxy.getIntlayerAPIProxy(void 0, config);
		const getDictionariesUpdateTimestampResult = await intlayerAPI.dictionary.getDictionariesUpdateTimestamp();
		if (!getDictionariesUpdateTimestampResult.data) throw new Error("No distant dictionaries found");
		let distantDictionariesUpdateTimeStamp = getDictionariesUpdateTimestampResult.data;
		if (options?.dictionaries) distantDictionariesUpdateTimeStamp = Object.fromEntries(Object.entries(distantDictionariesUpdateTimeStamp).filter(([key]) => options.dictionaries?.includes(key)));
		const remoteDictionariesPath = (0, node_path.join)(config.content.mainDir, "remote_dictionaries.cjs");
		const requireFunction = config.build?.require ?? require_ESMxCJSHelpers.getProjectRequire();
		const remoteDictionariesRecord = (0, node_fs.existsSync)(remoteDictionariesPath) ? requireFunction(remoteDictionariesPath) : {};
		const entries = Object.entries(distantDictionariesUpdateTimeStamp);
		const keysToFetch = entries.filter(([key, remoteUpdatedAt]) => {
			if (!remoteUpdatedAt) return true;
			const local = remoteDictionariesRecord[key];
			if (!local) return true;
			const localUpdatedAtRaw = local?.updatedAt;
			const localUpdatedAt = typeof localUpdatedAtRaw === "number" ? localUpdatedAtRaw : localUpdatedAtRaw ? new Date(localUpdatedAtRaw).getTime() : void 0;
			if (typeof localUpdatedAt !== "number") return true;
			return remoteUpdatedAt > localUpdatedAt;
		}).map(([key]) => key);
		const cachedKeys = entries.filter(([key, remoteUpdatedAt]) => {
			const localUpdatedAtRaw = remoteDictionariesRecord[key]?.updatedAt;
			const localUpdatedAt = typeof localUpdatedAtRaw === "number" ? localUpdatedAtRaw : localUpdatedAtRaw ? new Date(localUpdatedAtRaw).getTime() : void 0;
			return typeof localUpdatedAt === "number" && typeof remoteUpdatedAt === "number" && localUpdatedAt >= remoteUpdatedAt;
		}).map(([key]) => key);
		if (entries.length === 0) {
			appLogger("No dictionaries to fetch", { level: "error" });
			return;
		}
		appLogger("Fetching dictionaries:");
		const dictionariesStatuses = [...cachedKeys.map((dictionaryKey) => ({
			dictionaryKey,
			status: "imported"
		})), ...keysToFetch.map((dictionaryKey) => ({
			dictionaryKey,
			status: "pending"
		}))];
		const logger$1 = new require_pullLog.PullLogger();
		logger$1.update(dictionariesStatuses.map((s) => ({
			dictionaryKey: s.dictionaryKey,
			status: s.status
		})));
		const successfullyFetchedDictionaries = [];
		const processDictionary = async (statusObj) => {
			const isCached = statusObj.status === "imported" || statusObj.status === "up-to-date";
			if (!isCached) {
				statusObj.status = "fetching";
				logger$1.update([{
					dictionaryKey: statusObj.dictionaryKey,
					status: "fetching"
				}]);
			}
			try {
				let sourceDictionary;
				if (isCached) sourceDictionary = remoteDictionariesRecord[statusObj.dictionaryKey];
				if (!sourceDictionary) sourceDictionary = (await intlayerAPI.dictionary.getDictionary(statusObj.dictionaryKey)).data;
				if (!sourceDictionary) throw new Error(`Dictionary ${statusObj.dictionaryKey} not found on remote`);
				const { status } = await require_writeContentDeclaration.writeContentDeclaration(sourceDictionary, config, options);
				statusObj.status = status;
				logger$1.update([{
					dictionaryKey: statusObj.dictionaryKey,
					status
				}]);
				successfullyFetchedDictionaries.push(sourceDictionary);
			} catch (error) {
				statusObj.status = "error";
				statusObj.error = error;
				statusObj.errorMessage = `Error fetching dictionary ${statusObj.dictionaryKey}: ${error}`;
				logger$1.update([{
					dictionaryKey: statusObj.dictionaryKey,
					status: "error"
				}]);
			}
		};
		await require_parallelize.parallelize(dictionariesStatuses, processDictionary, 5);
		logger$1.finish();
		const iconFor = (status) => {
			switch (status) {
				case "fetched":
				case "imported":
				case "updated":
				case "up-to-date":
				case "reimported in JSON":
				case "new content file": return "✔";
				case "error": return "✖";
				default: return "⏲";
			}
		};
		const colorFor = (status) => {
			switch (status) {
				case "fetched":
				case "imported":
				case "updated":
				case "up-to-date": return require_logger.ANSIColors.GREEN;
				case "reimported in JSON":
				case "new content file": return require_logger.ANSIColors.YELLOW;
				case "error": return require_logger.ANSIColors.RED;
				default: return require_logger.ANSIColors.BLUE;
			}
		};
		for (const s of dictionariesStatuses) {
			const icon = iconFor(s.status);
			const color = colorFor(s.status);
			appLogger(` - ${s.dictionaryKey} ${require_logger.ANSIColors.GREY}[${color}${icon} ${s.status}${require_logger.ANSIColors.GREY}]${require_logger.ANSIColors.RESET}`);
		}
		for (const statusObj of dictionariesStatuses) if (statusObj.errorMessage) appLogger(statusObj.errorMessage, { level: "error" });
	} catch (error) {
		appLogger(error, { level: "error" });
	}
};

//#endregion
exports.pull = pull;
//# sourceMappingURL=pull.cjs.map