"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
const HasKey_1 = require("./Nodes/HasKey");
var generate = require('@babel/generator');
const path = require('path');
const t = require("@babel/types");
const HardCode_1 = require("./Nodes/HardCode");
module.exports = class {
    constructor(options) {
        // @ts-ignore
        this.langRegexp = {
            zh_CN: /[\u4e00-\u9fa5]/
        };
        this.options = options;
    }
    apply(parser) {
        this.config = parser.config;
        this.parser = parser;
        const { babelHooks, intlStorage, webViewHooks } = parser;
        this.intlStorage = intlStorage;
        babelHooks.babelPluginHook.tap('plugin', ((plugins) => {
            return plugins.concat([
                {
                    visitor: {
                        JSXText: (nodePath) => {
                            this.checkNode(nodePath);
                        },
                        StringLiteral: (nodePath) => {
                            this.checkNode(nodePath);
                        },
                        TemplateElement: (nodePath) => {
                            this.checkNode(nodePath);
                        },
                    }
                },
            ]);
        }));
        this.parser.webview.addParentListener('onErrorInfoReplace', (errorInfo) => {
            var _a, _b;
            // 找到对应的ErrorNode 节点，然后调用replace方法
            const errorNode = (_b = (_a = this.parser) === null || _a === void 0 ? void 0 : _a.parserManager.caches[errorInfo.filePath]) === null || _b === void 0 ? void 0 : _b.errors.find((item) => {
                return item.id === errorInfo.id;
            });
            errorNode === null || errorNode === void 0 ? void 0 : errorNode.replaceAndSave(errorInfo);
        });
        this.parser.webview.addParentListener('onErrorInfoReplaceWithKuohao', (errorInfo) => {
            var _a, _b;
            // 找到对应的ErrorNode 节点，然后调用replace方法
            const errorNode = (_b = (_a = this.parser) === null || _a === void 0 ? void 0 : _a.parserManager.caches[errorInfo.filePath]) === null || _b === void 0 ? void 0 : _b.errors.find((item) => {
                return item.id === errorInfo.id;
            });
            errorNode === null || errorNode === void 0 ? void 0 : errorNode.replaceAndSaveWithBrackets(errorInfo);
        });
        webViewHooks.btnHook.tapPromise('replace', (btns) => __awaiter(this, void 0, void 0, function* () {
            return btns.concat([
                {
                    key: 'replace',
                    text: '替换',
                    functionConstructorParams: [
                        'errorInfo',
                        `
                            triggerParentListener('onErrorInfoReplace', errorInfo);
                        `
                    ]
                },
                {
                    key: 'replaceWithBrackets',
                    text: '替换并加大括号',
                    functionConstructorParams: [
                        'errorInfo',
                        `
                            triggerParentListener('onErrorInfoReplaceWithKuohao', errorInfo);
                        `
                    ]
                }
            ]);
        }));
    }
    getNodeValue(node) {
        var value = '';
        if (node.type === 'TemplateElement') {
            value = node.value.raw;
        }
        else {
            value = node.value;
        }
        return value.trim();
    }
    checkNode(nodePath) {
        var _a, _b;
        let nodeValue = this.getNodeValue(nodePath.node);
        if (this.langRegexp[this.options.defaultLang].test(nodeValue)) {
            const filePath = nodePath.hub.file.opts.filename;
            const intlNode = nodePath.findParent((item) => {
                const node = item.node;
                if (node.type === "CallExpression"
                    && node.callee.type === "MemberExpression"
                    && this.options.defaultFuncNameReg.test(node.callee.property.name)) {
                    const objNode = node.callee.object;
                    if (objNode.type === "CallExpression"
                        && this.options.getFuncNameReg.test(objNode.callee.property.name)
                        && objNode.callee.object.type === "Identifier"
                        && objNode.callee.object.name === "intl") {
                        return true;
                    }
                }
                return false;
            });
            let hasParams = false;
            if (intlNode) {
                const intlKey = intlNode.node.callee.object.arguments[0].value;
                const intlText = generate.default(intlNode.node.arguments[0]).code.slice(1, -1);
                const locNode = intlNode.node.loc;
                if (intlNode.node.start
                    || intlNode.node.end
                    || locNode.start
                    || locNode.end) {
                    const keyNode = intlNode.node.callee.object.arguments[0];
                    const textNode = intlNode.node.arguments[0];
                    // 这里因为会重复创建很多个ErrorNode, 不太好解决
                    (_a = this.parser) === null || _a === void 0 ? void 0 : _a.pushError(new HasKey_1.default({
                        parser: this.parser,
                        filepath: filePath,
                        start: intlNode.node.start,
                        end: intlNode.node.end,
                        startRow: locNode.start.line,
                        startCol: locNode.start.column,
                        endRow: locNode.end.line,
                        endCol: locNode.end.column,
                    }, {
                        key: intlKey,
                        text: intlText,
                        keyStart: keyNode.start,
                        keyEnd: keyNode.end,
                        textStart: textNode.start,
                        textEnd: textNode.end,
                    }));
                }
            }
            else { // 硬编码
                let node = nodePath.node;
                let replaceParams = null;
                // 对模板字符串单独处理
                if (node.type === 'TemplateElement') {
                    let newNodePath = nodePath.findParent((item) => {
                        return item.node.type === 'TemplateLiteral';
                    });
                    if (newNodePath) {
                        node = newNodePath.node;
                        const properties = [];
                        var params = [];
                        node.expressions.forEach((value, index) => {
                            params.push(`{key${index}}`);
                            properties.push(t.objectProperty(t.identifier(`key${index}`), value));
                        });
                        if (properties.length > 0) {
                            hasParams = true;
                            replaceParams = generate.default(t.objectExpression(properties), { compact: true }).code;
                        }
                        const replaceTextArr = [];
                        node.quasis.forEach((item) => {
                            replaceTextArr.push(item.value.raw);
                            if (params.length) {
                                replaceTextArr.push(params.shift());
                            }
                        });
                        nodeValue = replaceTextArr.join('');
                    }
                }
                if (node && node.loc) {
                    const locNode = node.loc;
                    if (node.start
                        || node.end
                        || locNode.start
                        || locNode.end) {
                        const isHtml = /<(?:html|head|title|base|link|meta|style|script|noscript|template|body|section|nav|article|aside|h1|h2|h3|h4|h5|h6|header|footer|address|main|p|hr|pre|blockquote|ol|ul|li|dl|dt|dd|figure|figcaption|div|a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img|iframe|embed|object|param|video|audio|source|track|canvas|map|area|svg|math|table|caption|colgroup|col|tbody|thead|tfoot|tr|td|th|form|fieldset|legend|label|input|button|select|datalist|optgroup|option|textarea|keygen|output|progress|meter|details|summary|menuitem|menu)[^>]*>/;
                        (_b = this.parser) === null || _b === void 0 ? void 0 : _b.pushError(new HardCode_1.default({
                            parser: this.parser,
                            filepath: filePath,
                            start: node.start,
                            end: node.end,
                            startRow: locNode.start.line,
                            startCol: locNode.start.column,
                            endRow: locNode.end.line,
                            endCol: locNode.end.column,
                        }, {
                            text: nodeValue,
                            params: replaceParams,
                            getMethod: isHtml.test(nodeValue) ? 'getHTML' : 'get'
                        }));
                    }
                    else {
                        throw (new Error('缺少位置信息'));
                    }
                }
            }
        }
    }
};
//# sourceMappingURL=index.js.map