'use strict';

const require_runtime = require('../_virtual/_rolldown/runtime.js');
const require_index = require('../utils/index.js');

//#region lib/rules/prefer-separate-static-class.js
/**
* @author Flo Edelmann
* See LICENSE file in root directory for full license.
*/
var require_prefer_separate_static_class = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
	const { defineTemplateBodyVisitor, isStringLiteral, getStringLiteralValue } = require_index.default;
	/**
	* @param {Expression | VForExpression | VOnExpression | VSlotScopeExpression | VFilterSequenceExpression} expressionNode
	* @returns {(Literal | TemplateLiteral | Identifier)[]}
	*/
	function findStaticClasses(expressionNode) {
		if (isStringLiteral(expressionNode)) return [expressionNode];
		if (expressionNode.type === "ArrayExpression") return expressionNode.elements.flatMap((element) => {
			if (element === null || element.type === "SpreadElement") return [];
			return findStaticClasses(element);
		});
		if (expressionNode.type === "ObjectExpression") return expressionNode.properties.flatMap((property) => {
			if (property.type === "Property" && property.value.type === "Literal" && property.value.value === true && (isStringLiteral(property.key) || property.key.type === "Identifier" && !property.computed)) return [property.key];
			return [];
		});
		return [];
	}
	/**
	* @param {VAttribute | VDirective} attributeNode
	* @returns {attributeNode is VAttribute & { value: VLiteral }}
	*/
	function isStaticClassAttribute(attributeNode) {
		return !attributeNode.directive && attributeNode.key.name === "class" && attributeNode.value !== null;
	}
	/**
	* Removes the node together with the comma before or after the node.
	* @param {RuleFixer} fixer
	* @param {ParserServices.TokenStore} tokenStore
	* @param {ASTNode} node
	*/
	function* removeNodeWithComma(fixer, tokenStore, node) {
		const prevToken = tokenStore.getTokenBefore(node);
		if (prevToken.type === "Punctuator" && prevToken.value === ",") {
			yield fixer.removeRange([prevToken.range[0], node.range[1]]);
			return;
		}
		const [nextToken, nextNextToken] = tokenStore.getTokensAfter(node, { count: 2 });
		if (nextToken.type === "Punctuator" && nextToken.value === "," && (nextNextToken.type !== "Punctuator" || nextNextToken.value !== "]" && nextNextToken.value !== "}")) {
			yield fixer.removeRange([node.range[0], nextNextToken.range[0]]);
			return;
		}
		yield fixer.remove(node);
	}
	module.exports = {
		meta: {
			type: "suggestion",
			docs: {
				description: "require static class names in template to be in a separate `class` attribute",
				categories: void 0,
				url: "https://eslint.vuejs.org/rules/prefer-separate-static-class.html"
			},
			fixable: "code",
			schema: [],
			messages: { preferSeparateStaticClass: "Static class \"{{className}}\" should be in a static `class` attribute." }
		},
		create(context) {
			return defineTemplateBodyVisitor(context, { "VAttribute[directive=true] > VDirectiveKey[name.name='bind'][argument.name='class']"(directiveKeyNode) {
				const attributeNode = directiveKeyNode.parent;
				if (!attributeNode.value || !attributeNode.value.expression) return;
				const expressionNode = attributeNode.value.expression;
				const staticClassNameNodes = findStaticClasses(expressionNode);
				for (const staticClassNameNode of staticClassNameNodes) {
					const className = staticClassNameNode.type === "Identifier" ? staticClassNameNode.name : getStringLiteralValue(staticClassNameNode, true);
					if (className === null) continue;
					context.report({
						node: staticClassNameNode,
						messageId: "preferSeparateStaticClass",
						data: { className },
						*fix(fixer) {
							let dynamicClassDirectiveRemoved = false;
							yield* removeFromClassDirective();
							yield* addToClassAttribute();
							/**
							* Remove class from dynamic `:class` directive.
							*/
							function* removeFromClassDirective() {
								if (isStringLiteral(expressionNode)) {
									yield fixer.remove(attributeNode);
									dynamicClassDirectiveRemoved = true;
									return;
								}
								const listElement = staticClassNameNode.parent.type === "Property" ? staticClassNameNode.parent : staticClassNameNode;
								const listNode = listElement.parent;
								if (listNode.type === "ArrayExpression" || listNode.type === "ObjectExpression") {
									const elements = listNode.type === "ObjectExpression" ? listNode.properties : listNode.elements;
									if (elements.length === 1 && listNode === expressionNode) {
										yield fixer.remove(attributeNode);
										dynamicClassDirectiveRemoved = true;
										return;
									}
									const tokenStore = context.sourceCode.parserServices.getTemplateBodyTokenStore();
									if (elements.length === 1) {
										yield* removeNodeWithComma(fixer, tokenStore, listNode);
										return;
									}
									yield* removeNodeWithComma(fixer, tokenStore, listElement);
								}
							}
							/**
							* Add class to static `class` attribute.
							*/
							function* addToClassAttribute() {
								const existingStaticClassAttribute = attributeNode.parent.attributes.find(isStaticClassAttribute);
								if (existingStaticClassAttribute) {
									const literalNode = existingStaticClassAttribute.value;
									yield fixer.replaceText(literalNode, `"${literalNode.value} ${className}"`);
									return;
								}
								const separator = dynamicClassDirectiveRemoved ? "" : " ";
								yield fixer.insertTextBefore(attributeNode, `class="${className}"${separator}`);
							}
						}
					});
				}
			} });
		}
	};
}));

//#endregion
Object.defineProperty(exports, 'default', {
  enumerable: true,
  get: function () {
    return require_prefer_separate_static_class();
  }
});