"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.detect = exports.getNameCasing = exports.convertAttrName = exports.convertTagName = void 0;
const shared_1 = require("@vue/shared");
const helpers_1 = require("../helpers");
const vue = require("@vue/language-core");
const types_1 = require("../types");
async function convertTagName(ts, context, uri, casing, vueCompilerOptions) {
    const rootFile = context.documents.getSourceByUri(uri)?.root;
    if (!(rootFile instanceof vue.VueFile))
        return;
    const desc = rootFile.sfc;
    if (!desc.template)
        return;
    const languageService = context.inject('typescript/languageService');
    const template = desc.template;
    const document = context.documents.getDocumentByFileName(rootFile.snapshot, rootFile.fileName);
    const edits = [];
    const components = (0, helpers_1.checkComponentNames)(ts, languageService, rootFile, vueCompilerOptions);
    const tags = (0, helpers_1.getTemplateTagsAndAttrs)(rootFile);
    for (const [tagName, { offsets }] of tags) {
        const componentName = components.find(component => component === tagName || (0, shared_1.hyphenate)(component) === tagName);
        if (componentName) {
            for (const offset of offsets) {
                const start = document.positionAt(template.startTagEnd + offset);
                const end = document.positionAt(template.startTagEnd + offset + tagName.length);
                const range = { start, end };
                if (casing === types_1.TagNameCasing.Kebab && tagName !== (0, shared_1.hyphenate)(componentName)) {
                    edits.push({ range, newText: (0, shared_1.hyphenate)(componentName) });
                }
                if (casing === types_1.TagNameCasing.Pascal && tagName !== componentName) {
                    edits.push({ range, newText: componentName });
                }
            }
        }
    }
    return edits;
}
exports.convertTagName = convertTagName;
async function convertAttrName(ts, context, uri, casing, vueCompilerOptions) {
    const rootFile = context.documents.getSourceByUri(uri)?.root;
    if (!(rootFile instanceof vue.VueFile))
        return;
    const desc = rootFile.sfc;
    if (!desc.template)
        return;
    const languageService = context.inject('typescript/languageService');
    const template = desc.template;
    const document = context.documents.getDocumentByFileName(rootFile.snapshot, rootFile.fileName);
    const edits = [];
    const components = (0, helpers_1.checkComponentNames)(ts, languageService, rootFile, vueCompilerOptions);
    const tags = (0, helpers_1.getTemplateTagsAndAttrs)(rootFile);
    for (const [tagName, { attrs }] of tags) {
        const componentName = components.find(component => component === tagName || (0, shared_1.hyphenate)(component) === tagName);
        if (componentName) {
            const props = (0, helpers_1.checkPropsOfTag)(ts, languageService, rootFile, componentName, vueCompilerOptions);
            for (const [attrName, { offsets }] of attrs) {
                const propName = props.find(prop => prop === attrName || (0, shared_1.hyphenate)(prop) === attrName);
                if (propName) {
                    for (const offset of offsets) {
                        const start = document.positionAt(template.startTagEnd + offset);
                        const end = document.positionAt(template.startTagEnd + offset + attrName.length);
                        const range = { start, end };
                        if (casing === types_1.AttrNameCasing.Kebab && attrName !== (0, shared_1.hyphenate)(propName)) {
                            edits.push({ range, newText: (0, shared_1.hyphenate)(propName) });
                        }
                        if (casing === types_1.AttrNameCasing.Camel && attrName !== propName) {
                            edits.push({ range, newText: propName });
                        }
                    }
                }
            }
        }
    }
    return edits;
}
exports.convertAttrName = convertAttrName;
async function getNameCasing(ts, context, uri, vueCompilerOptions) {
    const detected = detect(ts, context, uri, vueCompilerOptions);
    const [attr, tag] = await Promise.all([
        context.env.getConfiguration?.('vue.complete.casing.props', uri),
        context.env.getConfiguration?.('vue.complete.casing.tags', uri),
    ]);
    const tagNameCasing = detected.tag.length === 1 && (tag === 'autoPascal' || tag === 'autoKebab') ? detected.tag[0] : (tag === 'autoKebab' || tag === 'kebab') ? types_1.TagNameCasing.Kebab : types_1.TagNameCasing.Pascal;
    const attrNameCasing = detected.attr.length === 1 && (attr === 'autoCamel' || attr === 'autoKebab') ? detected.attr[0] : (attr === 'autoCamel' || attr === 'camel') ? types_1.AttrNameCasing.Camel : types_1.AttrNameCasing.Kebab;
    return {
        tag: tagNameCasing,
        attr: attrNameCasing,
    };
}
exports.getNameCasing = getNameCasing;
function detect(ts, context, uri, vueCompilerOptions) {
    const rootFile = context.documents.getSourceByUri(uri)?.root;
    if (!(rootFile instanceof vue.VueFile)) {
        return {
            tag: [],
            attr: [],
        };
    }
    const languageService = context.inject('typescript/languageService');
    return {
        tag: getTagNameCase(rootFile),
        attr: getAttrNameCase(rootFile),
    };
    function getAttrNameCase(file) {
        const tags = (0, helpers_1.getTemplateTagsAndAttrs)(file);
        const result = [];
        for (const [_, { attrs }] of tags) {
            for (const [tagName] of attrs) {
                // attrName
                if (tagName !== (0, shared_1.hyphenate)(tagName)) {
                    result.push(types_1.AttrNameCasing.Camel);
                    break;
                }
            }
            for (const [tagName] of attrs) {
                // attr-name
                if (tagName.indexOf('-') >= 0) {
                    result.push(types_1.AttrNameCasing.Kebab);
                    break;
                }
            }
        }
        return result;
    }
    function getTagNameCase(file) {
        const components = (0, helpers_1.checkComponentNames)(ts, languageService, file, vueCompilerOptions);
        const tagNames = (0, helpers_1.getTemplateTagsAndAttrs)(file);
        const result = [];
        let anyComponentUsed = false;
        for (const component of components) {
            if (tagNames.has(component) || tagNames.has((0, shared_1.hyphenate)(component))) {
                anyComponentUsed = true;
                break;
            }
        }
        if (!anyComponentUsed) {
            return []; // not sure component style, because do not have any component using in <template> for check
        }
        for (const [tagName] of tagNames) {
            // TagName
            if (tagName !== (0, shared_1.hyphenate)(tagName)) {
                result.push(types_1.TagNameCasing.Pascal);
                break;
            }
        }
        for (const component of components) {
            // Tagname -> tagname
            // TagName -> tag-name
            if (component !== (0, shared_1.hyphenate)(component) && tagNames.has((0, shared_1.hyphenate)(component))) {
                result.push(types_1.TagNameCasing.Kebab);
                break;
            }
        }
        return result;
    }
}
exports.detect = detect;
//# sourceMappingURL=nameCasing.js.map