/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * <p>This source code is licensed under the MIT license found in the LICENSE file in the root
 * directory of this source tree.
 */
package com.facebook.react;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * {@code CompositeReactPackage} allows to create a single package composed of views and modules
 * from several other packages.
 */
public class CompositeReactPackage implements ViewManagerOnDemandReactPackage, ReactPackage {

  private final List<ReactPackage> mChildReactPackages = new ArrayList<>();

  /**
   * The order in which packages are passed matters. It may happen that a NativeModule or a
   * ViewManager exists in two or more ReactPackages. In that case the latter will win i.e. the
   * latter will overwrite the former. This re-occurrence is detected by comparing a name of a
   * module.
   */
  public CompositeReactPackage(ReactPackage arg1, ReactPackage arg2, ReactPackage... args) {
    mChildReactPackages.add(arg1);
    mChildReactPackages.add(arg2);

    Collections.addAll(mChildReactPackages, args);
  }

  /** {@inheritDoc} */
  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    // This is for backward compatibility.
    final Map<String, NativeModule> moduleMap = new HashMap<>();
    for (ReactPackage reactPackage : mChildReactPackages) {
      for (NativeModule nativeModule : reactPackage.createNativeModules(reactContext)) {
        moduleMap.put(nativeModule.getName(), nativeModule);
      }
    }
    return new ArrayList<>(moduleMap.values());
  }

  /** {@inheritDoc} */
  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    final Map<String, ViewManager> viewManagerMap = new HashMap<>();
    for (ReactPackage reactPackage : mChildReactPackages) {
      for (ViewManager viewManager : reactPackage.createViewManagers(reactContext)) {
        viewManagerMap.put(viewManager.getName(), viewManager);
      }
    }
    return new ArrayList<>(viewManagerMap.values());
  }

  /** {@inheritDoc} */
  @Override
  public List<String> getViewManagerNames(ReactApplicationContext reactContext) {
    Set<String> uniqueNames = new HashSet<>();
    for (ReactPackage reactPackage : mChildReactPackages) {
      if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
        List<String> names =
            ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(reactContext);
        if (names != null) {
          uniqueNames.addAll(names);
        }
      }
    }
    return new ArrayList<>(uniqueNames);
  }

  /** {@inheritDoc} */
  @Override
  public @Nullable ViewManager createViewManager(
      ReactApplicationContext reactContext, String viewManagerName) {
    ListIterator<ReactPackage> iterator =
        mChildReactPackages.listIterator(mChildReactPackages.size());
    while (iterator.hasPrevious()) {
      ReactPackage reactPackage = iterator.previous();
      if (reactPackage instanceof ViewManagerOnDemandReactPackage) {
        ViewManager viewManager =
            ((ViewManagerOnDemandReactPackage) reactPackage)
                .createViewManager(reactContext, viewManagerName);
        if (viewManager != null) {
          return viewManager;
        }
      }
    }
    return null;
  }
}

@@ -319,16 +319,136 @@
 ontext;%0A
+import com.facebook.react.module.model.ReactModuleInfo;%0Aimport com.facebook.react.module.model.ReactModuleInfoProvider;%0A
 import c
@@ -484,24 +484,24 @@
 iewManager;%0A
-
 import java.
@@ -729,16 +729,61 @@
 ullable;
+%0Aimport com.facebook.react.TurboReactPackage;
 %0A%0A/**%0A *
@@ -1836,32 +1836,32 @@
 ew HashMap%3C%3E();%0A
-
     for (ReactPa
@@ -1896,32 +1896,823 @@
 eactPackages) %7B%0A
+      /**%0A       * For now, we eagerly initialize the NativeModules inside TurboReactPackages.%0A       * Ultimately, we should turn CompositeReactPackage into a TurboReactPackage%0A       * and remove this eager initialization.%0A       *%0A       * TODO: T45627020%0A       */%0A      if (reactPackage instanceof TurboReactPackage) %7B%0A        TurboReactPackage turboReactPackage = (TurboReactPackage)reactPackage;%0A        ReactModuleInfoProvider moduleInfoProvider = turboReactPackage.getReactModuleInfoProvider();%0A        Map%3CString, ReactModuleInfo%3E moduleInfos = moduleInfoProvider.getReactModuleInfos();%0A%0A        for (final String moduleName : moduleInfos.keySet()) %7B%0A          moduleMap.put(moduleName, turboReactPackage.getModule(moduleName, reactContext));%0A        %7D%0A%0A        continue;%0A      %7D%0A%0A
       for (Nativ

Make CompositeReactPackage support TurboReactPackage