const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_utils_checkAccess = require('../utils/checkAccess.cjs');
const require_pushLog = require('../pushLog.cjs');
let __intlayer_api = require("@intlayer/api");
let __intlayer_chokidar = require("@intlayer/chokidar");
let __intlayer_config = require("@intlayer/config");
let node_path = require("node:path");
let __intlayer_unmerged_dictionaries_entry = require("@intlayer/unmerged-dictionaries-entry");
let node_fs_promises = require("node:fs/promises");
node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises);
let node_readline = require("node:readline");
node_readline = require_rolldown_runtime.__toESM(node_readline);

//#region src/push/push.ts
const statusIconsAndColors = {
	pushed: {
		icon: "✔",
		color: __intlayer_config.ANSIColors.GREEN
	},
	modified: {
		icon: "✔",
		color: __intlayer_config.ANSIColors.GREEN
	},
	error: {
		icon: "✖",
		color: __intlayer_config.ANSIColors.RED
	},
	default: {
		icon: "⏲",
		color: __intlayer_config.ANSIColors.BLUE
	}
};
const getIconAndColor = (status) => {
	return statusIconsAndColors[status] ?? statusIconsAndColors.default;
};
/**
* Get all local dictionaries and push them simultaneously.
*/
const push = async (options) => {
	const config = (0, __intlayer_config.getConfiguration)(options?.configOptions);
	const appLogger = (0, __intlayer_config.getAppLogger)(config, { config: { prefix: "" } });
	if (options?.build === true) await (0, __intlayer_chokidar.prepareIntlayer)(config, { forceRun: true });
	else if (typeof options?.build === "undefined") await (0, __intlayer_chokidar.prepareIntlayer)(config);
	try {
		if (!await require_utils_checkAccess.checkCMSAuth(config)) return;
		const intlayerAPI = (0, __intlayer_api.getIntlayerAPIProxy)(void 0, config);
		const unmergedDictionariesRecord = (0, __intlayer_unmerged_dictionaries_entry.getUnmergedDictionaries)(config);
		let dictionaries = Object.values(unmergedDictionariesRecord).flat();
		const existingDictionariesKeys = Object.keys(unmergedDictionariesRecord);
		if (options?.dictionaries) {
			const noneExistingDictionariesOption = options.dictionaries.filter((dictionaryId) => !existingDictionariesKeys.includes(dictionaryId));
			if (noneExistingDictionariesOption.length > 0) appLogger(`The following dictionaries do not exist: ${noneExistingDictionariesOption.join(", ")} and have been ignored.`, { level: "error" });
			dictionaries = dictionaries.filter((dictionary) => options.dictionaries?.includes(dictionary.key));
		}
		if (options?.gitOptions) {
			const gitFiles = await (0, __intlayer_chokidar.listGitFiles)(options.gitOptions);
			dictionaries = dictionaries.filter((dictionary) => gitFiles.includes((0, node_path.join)(config.content.baseDir, dictionary.filePath ?? "")));
		}
		if (dictionaries.length === 0) {
			appLogger("No local dictionaries found", { level: "error" });
			return;
		}
		appLogger("Pushing dictionaries:");
		const dictionariesStatuses = dictionaries.map((dictionary) => ({
			dictionary,
			status: "pending"
		}));
		const logger = new require_pushLog.PushLogger();
		logger.update(dictionariesStatuses.map((s) => ({
			dictionaryKey: s.dictionary.key,
			status: "pending"
		})));
		const successfullyPushedDictionaries = [];
		const processDictionary = async (statusObj) => {
			statusObj.status = "pushing";
			logger.update([{
				dictionaryKey: statusObj.dictionary.key,
				status: "pushing"
			}]);
			try {
				const pushResult = await intlayerAPI.dictionary.pushDictionaries([statusObj.dictionary]);
				const updatedDictionaries = pushResult.data?.updatedDictionaries ?? [];
				const newDictionaries = pushResult.data?.newDictionaries ?? [];
				const allDictionaries = [...updatedDictionaries, ...newDictionaries];
				for (const remoteDictionaryData of allDictionaries) {
					const localDictionary = unmergedDictionariesRecord[remoteDictionaryData.key]?.find((dictionary) => dictionary.localId === remoteDictionaryData.localId);
					if (!localDictionary) continue;
					await (0, __intlayer_chokidar.writeContentDeclaration)({
						...localDictionary,
						id: remoteDictionaryData.id
					}, config);
				}
				if (updatedDictionaries.some((dictionary) => dictionary.key === statusObj.dictionary.key)) {
					statusObj.status = "modified";
					successfullyPushedDictionaries.push(statusObj.dictionary);
					logger.update([{
						dictionaryKey: statusObj.dictionary.key,
						status: "modified"
					}]);
				} else if (newDictionaries.some((dictionary) => dictionary.key === statusObj.dictionary.key)) {
					statusObj.status = "pushed";
					successfullyPushedDictionaries.push(statusObj.dictionary);
					logger.update([{
						dictionaryKey: statusObj.dictionary.key,
						status: "pushed"
					}]);
				} else statusObj.status = "unknown";
			} catch (error) {
				statusObj.status = "error";
				statusObj.error = error;
				statusObj.errorMessage = `Error pushing dictionary ${statusObj.dictionary.key}: ${error}`;
				logger.update([{
					dictionaryKey: statusObj.dictionary.key,
					status: "error"
				}]);
			}
		};
		await (0, __intlayer_chokidar.parallelize)(dictionariesStatuses, processDictionary, 5);
		logger.finish();
		for (const dictionaryStatus of dictionariesStatuses) {
			const { icon, color } = getIconAndColor(dictionaryStatus.status);
			appLogger(` - ${dictionaryStatus.dictionary.key} ${__intlayer_config.ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${__intlayer_config.ANSIColors.GREY}]${__intlayer_config.ANSIColors.RESET}`);
		}
		for (const statusObj of dictionariesStatuses) if (statusObj.errorMessage) appLogger(statusObj.errorMessage, { level: "error" });
		const deleteOption = options?.deleteLocaleDictionary;
		const keepOption = options?.keepLocaleDictionary;
		if (deleteOption && keepOption) throw new Error("Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.");
		if (deleteOption) await deleteLocalDictionaries(successfullyPushedDictionaries, options);
		else if (keepOption) {} else {
			const answer = await askUser("Do you want to delete the local dictionaries that were successfully pushed? (yes/no): ");
			if (answer.toLowerCase() === "yes" || answer.toLowerCase() === "y") await deleteLocalDictionaries(successfullyPushedDictionaries, options);
		}
	} catch (error) {
		appLogger(error, { level: "error" });
	}
};
const askUser = (question) => {
	const rl = node_readline.createInterface({
		input: process.stdin,
		output: process.stdout
	});
	return new Promise((resolve) => {
		rl.question(question, (answer) => {
			rl.close();
			resolve(answer);
		});
	});
};
const deleteLocalDictionaries = async (dictionariesToDelete, options) => {
	const appLogger = (0, __intlayer_config.getAppLogger)((0, __intlayer_config.getConfiguration)(options?.configOptions), { config: { prefix: "" } });
	const filePathsSet = /* @__PURE__ */ new Set();
	for (const dictionary of dictionariesToDelete) {
		const { filePath } = dictionary;
		if (!filePath) {
			appLogger(`Dictionary ${dictionary.key} does not have a file path`, { level: "error" });
			continue;
		}
		filePathsSet.add(filePath);
	}
	for (const filePath of filePathsSet) try {
		const stats = await node_fs_promises.lstat(filePath);
		if (stats.isFile()) {
			await node_fs_promises.unlink(filePath);
			appLogger(`Deleted file ${(0, __intlayer_chokidar.formatPath)(filePath)}`, {});
		} else if (stats.isDirectory()) appLogger(`Path is a directory ${(0, __intlayer_chokidar.formatPath)(filePath)}, skipping.`, {});
		else appLogger(`Unknown file type for ${(0, __intlayer_chokidar.formatPath)(filePath)}, skipping.`, {});
	} catch (err) {
		appLogger(`Error deleting ${(0, __intlayer_chokidar.formatPath)(filePath)}: ${err}`, { level: "error" });
	}
};

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