const require_rolldown_runtime = require('../../../../../_virtual/rolldown_runtime.cjs');
const require_logger = require('../../../../config/dist/esm/logger.cjs');
const require_getConfiguration = require('../../../../config/dist/esm/configFile/getConfiguration.cjs');
const require_formatter = require('../chokidar/dist/esm/utils/formatter.cjs');
const require_parallelize = require('../chokidar/dist/esm/utils/parallelize.cjs');
const require_prepareIntlayer = require('../chokidar/dist/esm/prepareIntlayer.cjs');
const require_writeContentDeclaration = require('../chokidar/dist/esm/writeContentDeclaration/writeContentDeclaration.cjs');
const require_listGitFiles = require('../chokidar/dist/esm/listGitFiles.cjs');
const require_index = require('../unmerged-dictionaries-entry/dist/esm/index.cjs');
const require_proxy = require('../api/dist/esm/proxy.cjs');
const require_checkAccess = require('../utils/checkAccess.cjs');
const require_pushLog = require('../pushLog.cjs');
let node_path = require("node:path");
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 ../@intlayer/cli/dist/esm/push/push.mjs
const statusIconsAndColors = {
	pushed: {
		icon: "✔",
		color: require_logger.ANSIColors.GREEN
	},
	modified: {
		icon: "✔",
		color: require_logger.ANSIColors.GREEN
	},
	error: {
		icon: "✖",
		color: require_logger.ANSIColors.RED
	},
	default: {
		icon: "⏲",
		color: require_logger.ANSIColors.BLUE
	}
};
const getIconAndColor = (status) => {
	return statusIconsAndColors[status] ?? statusIconsAndColors.default;
};
/**
* Get all local dictionaries and push them simultaneously.
*/
const push = async (options) => {
	const config = require_getConfiguration.getConfiguration(options?.configOptions);
	const appLogger = require_logger.getAppLogger(config, { config: { prefix: "" } });
	if (options?.build === true) await require_prepareIntlayer.prepareIntlayer(config, { forceRun: true });
	else if (typeof options?.build === "undefined") await require_prepareIntlayer.prepareIntlayer(config);
	try {
		if (!await require_checkAccess.checkCMSAuth(config)) return;
		const intlayerAPI = require_proxy.getIntlayerAPIProxy(void 0, config);
		const unmergedDictionariesRecord = require_index.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 require_listGitFiles.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$1 = new require_pushLog.PushLogger();
		logger$1.update(dictionariesStatuses.map((s) => ({
			dictionaryKey: s.dictionary.key,
			status: "pending"
		})));
		const successfullyPushedDictionaries = [];
		const processDictionary = async (statusObj) => {
			statusObj.status = "pushing";
			logger$1.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 require_writeContentDeclaration.writeContentDeclaration({
						...localDictionary,
						id: remoteDictionaryData.id
					}, config);
				}
				if (updatedDictionaries.some((dictionary) => dictionary.key === statusObj.dictionary.key)) {
					statusObj.status = "modified";
					successfullyPushedDictionaries.push(statusObj.dictionary);
					logger$1.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$1.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$1.update([{
					dictionaryKey: statusObj.dictionary.key,
					status: "error"
				}]);
			}
		};
		await require_parallelize.parallelize(dictionariesStatuses, processDictionary, 5);
		logger$1.finish();
		for (const dictionaryStatus of dictionariesStatuses) {
			const { icon, color } = getIconAndColor(dictionaryStatus.status);
			appLogger(` - ${dictionaryStatus.dictionary.key} ${require_logger.ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${require_logger.ANSIColors.GREY}]${require_logger.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$1) => {
		rl.question(question, (answer) => {
			rl.close();
			resolve$1(answer);
		});
	});
};
const deleteLocalDictionaries = async (dictionariesToDelete, options) => {
	const appLogger = require_logger.getAppLogger(require_getConfiguration.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 ${require_formatter.formatPath(filePath)}`, {});
		} else if (stats.isDirectory()) appLogger(`Path is a directory ${require_formatter.formatPath(filePath)}, skipping.`, {});
		else appLogger(`Unknown file type for ${require_formatter.formatPath(filePath)}, skipping.`, {});
	} catch (err) {
		appLogger(`Error deleting ${require_formatter.formatPath(filePath)}: ${err}`, { level: "error" });
	}
};

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