"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AttrNameCasing = exports.TagNameCasing = void 0;
exports.checkCasing = checkCasing;
const language_core_1 = require("@vue/language-core");
var TagNameCasing;
(function (TagNameCasing) {
    TagNameCasing[TagNameCasing["Kebab"] = 0] = "Kebab";
    TagNameCasing[TagNameCasing["Pascal"] = 1] = "Pascal";
})(TagNameCasing || (exports.TagNameCasing = TagNameCasing = {}));
var AttrNameCasing;
(function (AttrNameCasing) {
    AttrNameCasing[AttrNameCasing["Kebab"] = 0] = "Kebab";
    AttrNameCasing[AttrNameCasing["Camel"] = 1] = "Camel";
})(AttrNameCasing || (exports.AttrNameCasing = AttrNameCasing = {}));
async function checkCasing(context, uri) {
    const detected = detect(context, uri);
    const [attr, tag] = await Promise.all([
        context.env.getConfiguration?.('vue.suggest.propNameCasing', uri.toString()),
        context.env.getConfiguration?.('vue.suggest.componentNameCasing', uri.toString()),
    ]);
    const tagNameCasing = detected.tag.length === 1 && (tag === 'preferPascalCase' || tag === 'preferKebabCase')
        ? detected.tag[0]
        : (tag === 'preferKebabCase' || tag === 'alwaysKebabCase')
            ? TagNameCasing.Kebab
            : TagNameCasing.Pascal;
    const attrNameCasing = detected.attr.length === 1 && (attr === 'preferCamelCase' || attr === 'preferKebabCase')
        ? detected.attr[0]
        : (attr === 'preferCamelCase' || attr === 'alwaysCamelCase')
            ? AttrNameCasing.Camel
            : AttrNameCasing.Kebab;
    return {
        tag: tagNameCasing,
        attr: attrNameCasing,
    };
}
const cache = new WeakMap();
function detect(context, uri) {
    const root = context.language.scripts.get(uri)?.generated?.root;
    if (!(root instanceof language_core_1.VueVirtualCode)) {
        return { tag: [], attr: [] };
    }
    return {
        tag: detectTagCasing(root),
        attr: detectAttrCasing(root),
    };
}
function detectAttrCasing(code) {
    let tags;
    if (cache.has(code)) {
        tags = cache.get(code);
    }
    else {
        cache.set(code, tags = collectTags(code));
    }
    const result = new Set();
    for (const [, attrs] of tags ?? []) {
        for (const attr of attrs) {
            // attrName
            if (attr !== (0, language_core_1.hyphenateTag)(attr)) {
                result.add(AttrNameCasing.Camel);
                break;
            }
        }
        for (const attr of attrs) {
            // attr-name
            if (attr.includes('-')) {
                result.add(AttrNameCasing.Kebab);
                break;
            }
        }
    }
    return [...result];
}
function detectTagCasing(code) {
    let tags;
    if (cache.has(code)) {
        tags = cache.get(code);
    }
    else {
        cache.set(code, tags = collectTags(code));
    }
    const result = new Set();
    for (const [tag] of tags ?? []) {
        if (tag !== (0, language_core_1.hyphenateTag)(tag)) {
            // TagName
            result.add(TagNameCasing.Pascal);
        }
        else {
            // tag-name
            result.add(TagNameCasing.Kebab);
        }
    }
    return [...result];
}
function collectTags(root) {
    if (!(root instanceof language_core_1.VueVirtualCode)) {
        return undefined;
    }
    const ast = root.sfc.template?.ast;
    if (!ast) {
        return undefined;
    }
    const tags = new Map();
    for (const node of (0, language_core_1.forEachElementNode)(ast)) {
        let tag = tags.get(node.tag);
        if (!tag) {
            tags.set(node.tag, tag = []);
        }
        for (const prop of node.props) {
            let name;
            if (prop.type === 7
                && prop.arg?.type === 4
                && prop.arg.isStatic) {
                name = prop.arg.content;
            }
            else if (prop.type === 6) {
                name = prop.name;
            }
            if (name !== undefined) {
                tag.push(name);
            }
        }
    }
    return tags;
}
//# sourceMappingURL=nameCasing.js.map