import addImports from 'jscodeshift-add-imports';

export default function transformer(fileInfo, api, options) {
  const j = api.jscodeshift;
  const importModule = options.importModule || '@mui/material';
  const targetModule = options.targetModule || '@mui/material';

  let requirePath = importModule;

  if (process.env.NODE_ENV === 'test') {
    requirePath = requirePath.replace(/^@mui\/material/, '../../../mui-material/src');
  }

  // eslint-disable-next-line global-require, import/no-dynamic-require
  const whitelist = require(requirePath);

  const printOptions = options.printOptions || {
    quote: 'single',
    trailingComma: true,
  };

  const root = j(fileInfo.source);
  const importRegExp = new RegExp(`^${importModule}/(?:[^/]+/)*([^/]+)$`);

  const resultSpecifiers = [];

  root.find(j.ImportDeclaration).forEach((path) => {
    if (!path.node.specifiers.length) {
      return;
    }

    if (path.value.importKind && path.value.importKind !== 'value') {
      return;
    }
    const importPath = path.value.source.value;
    const match = importPath.match(importRegExp);
    if (!match) {
      return;
    }

    if (importPath.includes('internal/')) {
      return;
    }

    path.node.specifiers.forEach((specifier, index) => {
      if (specifier.importKind && specifier.importKind !== 'value') {
        return;
      }
      if (specifier.type === 'ImportNamespaceSpecifier') {
        return;
      }

      switch (specifier.type) {
        case 'ImportDefaultSpecifier': {
          const localName = specifier.local.name;
          const moduleName = match[1];
          if (whitelist[moduleName] == null) {
            return;
          }
          resultSpecifiers.push(
            j.importSpecifier(j.identifier(moduleName), j.identifier(localName)),
          );
          path.get('specifiers', index).prune();
          break;
        }
        case 'ImportSpecifier':
          if (
            whitelist[specifier.imported.name] == null &&
            specifier.imported.name !== 'withStyles'
          ) {
            return;
          }
          resultSpecifiers.push(specifier);
          path.get('specifiers', index).prune();
          break;
        default:
          break;
      }
    });

    if (!path.node.specifiers.length) {
      path.prune();
    }
  });

  if (resultSpecifiers.length) {
    addImports(root, j.importDeclaration(resultSpecifiers, j.stringLiteral(targetModule)));
  }

  return root.toSource(printOptions);
}

@@ -1,12 +1,44 @@
+import %7B dirname %7D from 'path';%0A
 import addIm
@@ -79,512 +79,630 @@
 s';%0A
-%0Aexport default function transformer(fileInfo, api, options) %7B%0A  const j = api.jscodeshift;%0A  const importModule = options.importModule %7C%7C '@mui/material';%0A  const targetModule = options.targetModule %7C%7C '@mui/material';%0A%0A  let requirePath = importModule;%0A%0A  if (process.env.NODE_ENV === 'test') %7B%0A    requirePath = requirePath.replace(/%5E@mui%5C/material/, '../../../mui-material/src');%0A  %7D%0A%0A  // eslint-disable-next-line global-require, import/no-dynamic-require%0A  const whitelist = require(requirePath
+import getJSExports from '../util/getJSExports';%0A%0A// istanbul ignore next%0Aif (process.env.NODE_ENV === 'test') %7B%0A  const resolve = require.resolve;%0A  require.resolve = (source) =%3E%0A    resolve(source.replace(/%5E@mui%5C/material%5C/modern/, '../../../mui-material/src'));%0A%7D%0A%0Aexport default function transformer(fileInfo, api, options) %7B%0A  const j = api.jscodeshift;%0A  const importModule = options.importModule %7C%7C '@mui/material';%0A  const targetModule = options.targetModule %7C%7C '@mui/material';%0A%0A  const whitelist = getJSExports(%0A    require.resolve(%60$%7BimportModule%7D/modern%60, %7B%0A      paths: %5Bdirname(fileInfo.path)%5D,%0A    %7D),%0A  
 );%0A
-%0A
   co
@@ -1758,16 +1758,17 @@
     if (
+!
 whitelis
@@ -1768,17 +1768,21 @@
 hitelist
-%5B
+.has(
 moduleNa
@@ -1783,25 +1783,17 @@
 duleName
-%5D == null
+)
 ) %7B%0A    
@@ -2083,16 +2083,17 @@
         
+!
 whitelis
@@ -2093,17 +2093,21 @@
 hitelist
-%5B
+.has(
 specifie
@@ -2121,17 +2121,17 @@
 ted.name
-%5D
+)
  == null

Fix top level imports codemod (#31308)