"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_ID_INTERPOLATION_PATTERN = void 0;
const tslib_1 = require("tslib");
const helper_plugin_utils_1 = require("@babel/helper-plugin-utils");
const plugin_syntax_jsx_1 = tslib_1.__importDefault(require("@babel/plugin-syntax-jsx"));
const call_expression_1 = require("./visitors/call-expression");
const jsx_opening_element_1 = require("./visitors/jsx-opening-element");
exports.DEFAULT_ID_INTERPOLATION_PATTERN = '[sha512:contenthash:base64:6]';
const plugin = 
// @ts-expect-error PluginPass doesn't allow custom state but it actually does
(0, helper_plugin_utils_1.declare)((api, options) => {
    api.assertVersion(7);
    if (!options.idInterpolationPattern) {
        options.idInterpolationPattern = exports.DEFAULT_ID_INTERPOLATION_PATTERN;
    }
    const { pragma } = options;
    const componentNames = new Set(options.additionalComponentNames);
    componentNames.add('FormattedMessage');
    const functionNames = new Set(options.additionalFunctionNames);
    functionNames.add('formatMessage');
    // Short hand
    functionNames.add('$t');
    // Vue
    functionNames.add('$formatMessage');
    return {
        inherits: plugin_syntax_jsx_1.default,
        pre() {
            this.componentNames = Array.from(componentNames);
            this.functionNames = Array.from(functionNames);
        },
        visitor: {
            Program: {
                enter(path) {
                    this.messages = [];
                    this.meta = {};
                    if (!pragma) {
                        return;
                    }
                    for (const { leadingComments } of path.node.body) {
                        if (!leadingComments) {
                            continue;
                        }
                        const pragmaLineNode = leadingComments.find(c => c.value.includes(pragma));
                        if (!pragmaLineNode) {
                            continue;
                        }
                        pragmaLineNode.value
                            .split(pragma)[1]
                            .trim()
                            .split(/\s+/g)
                            .forEach(kv => {
                            const [k, v] = kv.split(':');
                            this.meta[k] = v;
                        });
                    }
                },
                exit(_, { opts: _opts, file: { opts: { filename }, }, }) {
                    const opts = _opts;
                    if (typeof opts?.onMetaExtracted === 'function') {
                        opts.onMetaExtracted(filename || '', this.meta);
                    }
                    if (typeof opts?.onMsgExtracted === 'function') {
                        opts.onMsgExtracted(filename || '', this.messages);
                    }
                },
            },
            JSXOpeningElement: jsx_opening_element_1.visitor,
            CallExpression: call_expression_1.visitor,
        },
    };
});
exports.default = plugin;
