/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-a795c5b | Cube Dev Team */
import { Lru } from "./lru.js";
import { Bucket, finalizeGroup, finalizePart, makeEmptyDetails, makeEmptyPart } from "./types.js";
import { classify } from "./classify.js";
import { scan } from "./tokenizer.js";

//#region src/tasty/parser/parser.ts
var StyleParser = class {
	cache;
	constructor(opts = {}) {
		this.opts = opts;
		this.cache = new Lru(this.opts.cacheSize ?? 1e3);
	}
	process(src) {
		const key = String(src);
		const hit = this.cache.get(key);
		if (hit) return hit;
		const stripped = src.replace(/\/\*[^*]*\*+(?:[^/*][^*]*\*+)*\//g, "").toLowerCase();
		const groups = [];
		let currentGroup = makeEmptyDetails();
		let currentPart = makeEmptyPart();
		let parts = [];
		const pushToken = (bucket, processed) => {
			if (!processed) return;
			const mergeIntoPrevUrl = () => {
				const lastIdx = currentPart.values.length - 1;
				currentPart.values[lastIdx] += ` ${processed}`;
				const lastAllIdx = currentPart.all.length - 1;
				currentPart.all[lastAllIdx] += ` ${processed}`;
			};
			if (currentPart.values.length > 0 && currentPart.values[currentPart.values.length - 1].startsWith("url(")) {
				mergeIntoPrevUrl();
				return;
			}
			switch (bucket) {
				case Bucket.Color:
					currentPart.colors.push(processed);
					break;
				case Bucket.Value:
					currentPart.values.push(processed);
					break;
				case Bucket.Mod:
					currentPart.mods.push(processed);
					break;
			}
			currentPart.all.push(processed);
		};
		const endPart = () => {
			if (currentPart.all.length > 0) {
				finalizePart(currentPart);
				parts.push(currentPart);
			}
			currentPart = makeEmptyPart();
		};
		const endGroup = () => {
			endPart();
			if (parts.length === 0) {
				parts.push(makeEmptyPart());
				finalizePart(parts[0]);
			}
			finalizeGroup(currentGroup, parts);
			groups.push(currentGroup);
			currentGroup = makeEmptyDetails();
			parts = [];
			currentPart = makeEmptyPart();
		};
		scan(stripped, (tok, isComma, isSlash, prevChar) => {
			if (tok) {
				if (currentGroup.input) currentGroup.input += ` ${tok}`;
				else currentGroup.input = tok;
				const { bucket, processed } = classify(tok, this.opts, (sub) => this.process(sub));
				pushToken(bucket, processed);
			}
			if (isSlash) endPart();
			if (isComma) endGroup();
		});
		if (currentPart.all.length || parts.length || !groups.length) endGroup();
		const result = {
			output: groups.map((g) => g.output).join(", "),
			groups
		};
		Object.freeze(result);
		this.cache.set(key, result);
		return result;
	}
	setFuncs(funcs) {
		this.opts.funcs = funcs;
		this.cache.clear();
	}
	setUnits(units) {
		this.opts.units = units;
		this.cache.clear();
	}
	updateOptions(patch) {
		Object.assign(this.opts, patch);
		if (patch.cacheSize) this.cache = new Lru(patch.cacheSize);
		else this.cache.clear();
	}
	/**
	* Clear the parser cache.
	* Call this when external state that affects parsing results has changed
	* (e.g., predefined tokens).
	*/
	clearCache() {
		this.cache.clear();
	}
	/**
	* Get the current units configuration.
	*/
	getUnits() {
		return this.opts.units;
	}
};

//#endregion
export { StyleParser };
//# sourceMappingURL=parser.js.map