import { isWorkerContext } from "../utils/isWorkerContext.js";
import { bundledLanguages } from "shiki";

//#region src/highlighter/languages.ts
const ResolvedLanguages = /* @__PURE__ */ new Map();
const ResolvingLanguages = /* @__PURE__ */ new Map();
const attachedLanguages = /* @__PURE__ */ new Set();
function getResolvedLanguages(languages) {
	const resolvedLanguages = [];
	for (const language of languages) {
		const resolvedLanguage = ResolvedLanguages.get(language);
		if (resolvedLanguage == null) throw new Error(`getResolvedLanguages: ${language} is not resolved. Please resolve languages before calling getResolvedLanguages`);
		resolvedLanguages.push(resolvedLanguage);
	}
	return resolvedLanguages;
}
function getResolvedOrResolveLanguage(language) {
	return ResolvedLanguages.get(language) ?? resolveLanguage(language);
}
function hasResolvedLanguages(languages) {
	for (const language of Array.isArray(languages) ? languages : [languages]) if (!ResolvedLanguages.has(language)) return false;
	return true;
}
async function resolveLanguage(lang) {
	if (isWorkerContext()) throw new Error(`resolveLanguage("${lang}") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);
	const resolver = ResolvingLanguages.get(lang);
	if (resolver != null) return resolver;
	try {
		const loader = bundledLanguages[lang];
		if (loader == null) throw new Error("resolveLanguage: \"${lang}\" not found in bundled languages");
		const resolver$1 = loader().then(({ default: data }) => {
			const resolvedLang = {
				name: lang,
				data
			};
			if (!ResolvedLanguages.has(lang)) ResolvedLanguages.set(lang, resolvedLang);
			return resolvedLang;
		});
		ResolvingLanguages.set(lang, resolver$1);
		return await resolver$1;
	} finally {
		ResolvingLanguages.delete(lang);
	}
}
async function resolveLanguages(languages) {
	const resolvedLanguages = [];
	const languagesToResolve = [];
	for (const language of languages) {
		if (language === "text") continue;
		const maybeResolvedLanguage = getResolvedOrResolveLanguage(language) ?? resolveLanguage(language);
		if ("then" in maybeResolvedLanguage) languagesToResolve.push(maybeResolvedLanguage);
		else resolvedLanguages.push(maybeResolvedLanguage);
	}
	if (languagesToResolve.length > 0) await Promise.all(languagesToResolve).then((_resolvedLanguages) => {
		for (const resolvedLanguage of _resolvedLanguages) {
			if (resolvedLanguage == null) throw new Error("resolvedLanguages: unable to resolve language");
			resolvedLanguages.push(resolvedLanguage);
		}
	});
	return resolvedLanguages;
}
function attachResolvedLanguages(resolvedLanguages, highlighter) {
	resolvedLanguages = Array.isArray(resolvedLanguages) ? resolvedLanguages : [resolvedLanguages];
	for (const resolvedLang of resolvedLanguages) {
		if (attachedLanguages.has(resolvedLang.name)) continue;
		let lang = ResolvedLanguages.get(resolvedLang.name);
		if (lang == null) {
			lang = resolvedLang;
			ResolvedLanguages.set(resolvedLang.name, lang);
		}
		attachedLanguages.add(lang.name);
		highlighter.loadLanguageSync(lang.data);
	}
}
function areLanguagesAttached(languages) {
	for (const language of Array.isArray(languages) ? languages : [languages]) if (!attachedLanguages.has(language)) return false;
	return true;
}
function cleanUpResolvedLanguages() {
	ResolvedLanguages.clear();
	attachedLanguages.clear();
}

//#endregion
export { areLanguagesAttached, attachResolvedLanguages, cleanUpResolvedLanguages, getResolvedLanguages, getResolvedOrResolveLanguage, hasResolvedLanguages, resolveLanguage, resolveLanguages };
//# sourceMappingURL=languages.js.map