/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 */

import {
  CallExpression,
  isStringLiteral,
  identifier,
  Identifier,
} from '@babel/types';
import {NodePath} from '@babel/traverse';

// This list should match `dispatcher/plugins.tsx` and `builtInModules` in `desktop/.eslintrc.js`
const requireReplacements: any = {
  flipper: 'global.Flipper',
  'flipper-plugin': 'global.FlipperPlugin',
  react: 'global.React',
  'react-dom': 'global.ReactDOM',
  'react-dom/client': 'global.ReactDOMClient',
  'react-is': 'global.ReactIs',
  antd: 'global.antd',
  immer: 'global.Immer',
  '@emotion/styled': 'global.emotion_styled',
  '@ant-design/icons': 'global.antdesign_icons',
};

export function tryReplaceFlipperRequire(path: NodePath<CallExpression>) {
  const node = path.node;
  const args = node.arguments || [];
  if (
    node.callee.type === 'Identifier' &&
    node.callee.name === 'require' &&
    args.length === 1 &&
    isStringLiteral(args[0])
  ) {
    const replacement = requireReplacements[args[0].value];
    if (replacement) {
      path.replaceWith(identifier(replacement));
      return true;
    }
  }
  return false;
}

export function tryReplaceGlobalReactUsage(path: NodePath<Identifier>) {
  if (
    path.node.name === 'React' &&
    (path.parentPath.node as any).id !== path.node &&
    path.parent.type !== 'ObjectProperty' &&
    !isReactImportIdentifier(path)
  ) {
    path.replaceWith(identifier('global.React'));
    return true;
  }
  return false;
}

function isReactImportIdentifier(path: NodePath<Identifier>) {
  return (
    path.parentPath.node.type === 'ImportNamespaceSpecifier' &&
    path.parentPath.node.local.name === 'React'
  );
}
