"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.create = create;
const language_core_1 = require("@vue/language-core");
const nameCasing_1 = require("../nameCasing");
const utils_1 = require("../utils");
function create({ getComponentProps }) {
    return {
        name: 'vue-missing-props-hints',
        capabilities: {
            inlayHintProvider: {},
        },
        create(context) {
            return {
                async provideInlayHints(document, range, cancellationToken) {
                    const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
                    if (info?.code.id !== 'template') {
                        return;
                    }
                    const enabled = await context.env.getConfiguration?.('vue.inlayHints.missingProps') ?? false;
                    if (!enabled) {
                        return;
                    }
                    const { template } = info.root.ir;
                    if (!template?.ast) {
                        return;
                    }
                    const result = [];
                    const attrNameCasing = await (0, nameCasing_1.getAttrNameCasing)(context, info.script.id);
                    const map = context.language.maps.get(info.code, info.script);
                    for (const node of (0, language_core_1.forEachElementNode)(template.ast)) {
                        if (cancellationToken.isCancellationRequested) {
                            break;
                        }
                        if (node.tagType !== 1) {
                            continue;
                        }
                        const [startTagOffset] = (0, language_core_1.getElementTagOffsets)(node, template);
                        const sourceOffset = startTagOffset + node.tag.length;
                        let generatedOffset;
                        for (const [offset] of map.toGeneratedLocation(template.startTagEnd + sourceOffset)) {
                            generatedOffset = offset;
                            break;
                        }
                        if (generatedOffset === undefined
                            || generatedOffset < document.offsetAt(range.start)
                            || generatedOffset > document.offsetAt(range.end)) {
                            continue;
                        }
                        const props = await getComponentProps(info.root.fileName, node.loc.start.offset) ?? [];
                        const missingProps = new Map(props.filter(prop => !prop.optional).map(prop => [(0, language_core_1.hyphenateAttr)(prop.name), prop.name]));
                        for (const prop of node.props) {
                            if (prop.type === 6) {
                                missingProps.delete((0, language_core_1.hyphenateAttr)(prop.name));
                            }
                            else if (prop.type === 7) {
                                if (prop.name === 'bind') {
                                    if (prop.arg?.type === 4 && prop.arg.isStatic) {
                                        missingProps.delete((0, language_core_1.hyphenateAttr)(prop.arg.content));
                                    }
                                    else if (!prop.arg) {
                                        missingProps.clear();
                                    }
                                }
                                else if (prop.name === 'model') {
                                    if (prop.arg?.type === 4 && prop.arg.isStatic) {
                                        missingProps.delete((0, language_core_1.hyphenateAttr)(prop.arg.content));
                                        missingProps.delete('on-update:' + (0, language_core_1.hyphenateAttr)(prop.arg.content));
                                    }
                                    else if (!prop.arg) {
                                        missingProps.delete('model-value');
                                        missingProps.delete('on-update:model-value');
                                    }
                                }
                                else if (prop.name === 'on') {
                                    if (prop.arg?.type === 4 && prop.arg.isStatic) {
                                        missingProps.delete('on-' + (0, language_core_1.hyphenateAttr)(prop.arg.content));
                                    }
                                }
                            }
                        }
                        for (const name of missingProps.values()) {
                            result.push({
                                label: name,
                                paddingLeft: true,
                                position: document.positionAt(generatedOffset),
                                kind: 2,
                                textEdits: [{
                                        range: {
                                            start: document.positionAt(generatedOffset),
                                            end: document.positionAt(generatedOffset),
                                        },
                                        newText: ` :${attrNameCasing === 0 /* AttrNameCasing.Kebab */ ? (0, language_core_1.hyphenateAttr)(name) : name}=`,
                                    }],
                            });
                        }
                    }
                    return result;
                },
            };
        },
    };
}
//# sourceMappingURL=vue-missing-props-hints.js.map