"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ts = require("typescript");
const getImportInfo = (importDeclaration) => {
    var _a;
    const moduleSpecifier = importDeclaration.moduleSpecifier.text;
    const namedBindings = (_a = importDeclaration.importClause) === null || _a === void 0 ? void 0 : _a.namedBindings;
    const importNameToAlias = {};
    if (namedBindings && ts.isNamedImports(namedBindings)) {
        namedBindings.forEachChild((node) => {
            var _a, _b;
            if (ts.isImportSpecifier(node)) {
                importNameToAlias[(_b = (_a = node.propertyName) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : node.name.text] = node.name.text;
            }
        });
    }
    return { moduleSpecifier, importNameToAlias };
};
/**
 * Internal webpack loader used to apply dynamic module import transformations.
 *
 * For example, the following import:
 * ```ts
 * import { Alert, AlertProps, Wizard } from '@patternfly/react-core';
 * ```
 * will be transformed into:
 * ```ts
 * import { Alert } from '@patternfly/react-core/dist/dynamic/components/Alert';
 * import { AlertProps } from '@patternfly/react-core/dist/dynamic/components/Alert';
 * import { Wizard } from '@patternfly/react-core/dist/dynamic/components/Wizard';
 * ```
 *
 * This loader requires the `typescript` package to be installed in the consuming project.
 *
 * @see https://webpack.js.org/contribute/writing-a-loader/
 */
const dynamicModuleImportLoader = function (source) {
    var _a;
    const { dynamicModuleMaps, resourceMetadata } = this.getOptions();
    const sourceContainsDynamicModuleReference = Object.keys(dynamicModuleMaps).some((m) => source.indexOf(m) !== -1);
    if (!sourceContainsDynamicModuleReference) {
        return source;
    }
    const sourceFile = ts.createSourceFile(this.resourcePath, source, ts.ScriptTarget.Latest, true, resourceMetadata.jsx ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
    // TypeScript compiler sets the 'parseDiagnostics' property on created SourceFile instances,
    // but does not expose it via SourceFile type definition. To avoid additional processing overhead
    // (i.e. creating a fake CompilerHost and associated Program) in order to access this information
    // (i.e. getSyntacticDiagnostics API), we access the 'parseDiagnostics' property directly here.
    const parseDiagnostics = (_a = sourceFile.parseDiagnostics) !== null && _a !== void 0 ? _a : [];
    const hasParseErrors = parseDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error).length > 0;
    if (hasParseErrors) {
        this.getLogger().warn(`Detected parse errors in ${this.resourcePath}`);
        return source;
    }
    const sourceReplacements = {};
    ts.forEachChild(sourceFile, (node) => {
        if (ts.isImportDeclaration(node)) {
            const { moduleSpecifier, importNameToAlias } = getImportInfo(node);
            const dynamicModuleName = Object.keys(dynamicModuleMaps).find((m) => moduleSpecifier.startsWith(m));
            if (!dynamicModuleName) {
                return;
            }
            const isIndexImport = moduleSpecifier === dynamicModuleName;
            if (isIndexImport && Object.keys(importNameToAlias).length > 0) {
                const dynamicImportStatements = [];
                Object.entries(importNameToAlias).forEach(([name, alias]) => {
                    const createImportStatement = (modulePath) => `import { ${name !== alias ? `${name} as ${alias}` : `${name}`} } from '${modulePath ? `${dynamicModuleName}/${modulePath}` : dynamicModuleName}';`;
                    const dynamicModulePath = dynamicModuleMaps[dynamicModuleName][name];
                    if (!dynamicModulePath) {
                        this.getLogger().warn(`No dynamic module found for ${name} in ${dynamicModuleName}`);
                    }
                    dynamicImportStatements.push(createImportStatement(dynamicModulePath));
                });
                sourceReplacements[node.getText(sourceFile)] = dynamicImportStatements.join('\n');
            }
            if (!isIndexImport &&
                !Object.values(dynamicModuleMaps[dynamicModuleName]).find((modulePath) => moduleSpecifier === `${dynamicModuleName}/${modulePath}`)) {
                this.getLogger().warn(`Non-index and non-dynamic module import ${moduleSpecifier}`);
            }
        }
    });
    return Object.entries(sourceReplacements).reduce((acc, [search, replacement]) => acc.replace(search, replacement), sourceFile.getFullText());
};
exports.default = dynamicModuleImportLoader;
//# sourceMappingURL=dynamic-module-import-loader.js.map