// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.ir.desugar;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;

// Summary:
// - Computes all the live nests reachable from Program Classes (Sequential), each time a
//  nest is computed, its processing starts concurrently.
// - Add bridges to be processed by further passes and create the maps
// for the lens (Sequential)
public class R8NestBasedAccessDesugaring extends NestBasedAccessDesugaring {

  public R8NestBasedAccessDesugaring(AppView<?> appView) {
    super(appView);
  }

  public NestedPrivateMethodLense run(
      ExecutorService executorService, DexApplication.Builder<?> appBuilder)
      throws ExecutionException {
    assert !appView.options().canUseNestBasedAccess()
        || appView.options().testing.enableForceNestBasedAccessDesugaringForTest;
    computeAndProcessNestsConcurrently(executorService);
    NestedPrivateMethodLense.Builder lensBuilder = NestedPrivateMethodLense.builder();
    addDeferredBridgesAndMapMethods(lensBuilder);
    clearNestAttributes();
    synthesizeNestConstructor(appBuilder);
    return lensBuilder.build(appView, getNestConstructorType());
  }

  private void addDeferredBridgesAndMapMethods(NestedPrivateMethodLense.Builder lensBuilder) {
    // Here we add the bridges and we fill the lens map.
    addDeferredBridgesAndMapMethods(bridges, lensBuilder::map);
    addDeferredBridgesAndMapMethods(getFieldBridges, lensBuilder::mapGetField);
    addDeferredBridgesAndMapMethods(putFieldBridges, lensBuilder::mapPutField);
  }

  private <E> void addDeferredBridgesAndMapMethods(
      Map<E, DexEncodedMethod> bridges, BiConsumer<E, DexMethod> lensInserter) {
    for (Map.Entry<E, DexEncodedMethod> entry : bridges.entrySet()) {
      DexClass holder = definitionFor(entry.getValue().method.holder);
      assert holder != null && holder.isProgramClass();
      holder.asProgramClass().addMethod(entry.getValue());
      lensInserter.accept(entry.getKey(), entry.getValue().method);
    }
    bridges.clear();
  }

  private void clearNestAttributes() {
    // Clearing nest attributes is required to allow class merging to be performed across nests
    // and to forbid other optimizations to introduce nest based accesses.
    for (DexClass clazz : appView.appInfo().classes()) {
      clazz.clearNestHost();
      clazz.getNestMembersClassAttributes().clear();
    }
  }

  private void computeAndProcessNestsConcurrently(ExecutorService executorService)
      throws ExecutionException {
    Set<DexType> nestHosts = Sets.newIdentityHashSet();
    ;
    List<Future<?>> futures = new ArrayList<>();
    // It is possible that a nest member is on the program path but its nest host
    // is only in the class path (or missing, raising an error).
    // Nests are therefore computed the first time a nest member is met, host or not.
    // The computedNestHosts list is there to avoid processing multiple times the same nest.
    for (DexProgramClass clazz : appView.appInfo().classes()) {
      if (clazz.isInANest()) {
        DexType hostType = clazz.getNestHost();
        if (!nestHosts.contains(hostType)) {
          nestHosts.add(hostType);
          futures.add(asyncProcessNest(clazz, executorService));
        }
      }
    }
    ThreadUtils.awaitFutures(futures);
  }

  // In R8, all classes are processed ahead of time.
  @Override
  protected boolean shouldProcessClassInNest(DexClass clazz, List<DexType> nest) {
    return true;
  }

  @Override
  void reportMissingNestHost(DexClass clazz) {
    if (appView.options().ignoreMissingClasses) {
      appView.options().nestDesugaringWarningMissingNestHost(clazz);
    } else {
      appView.options().errorMissingClassMissingNestHost(clazz);
    }
  }

  @Override
  void reportIncompleteNest(List<DexType> nest) {
    if (appView.options().ignoreMissingClasses) {
      appView.options().nestDesugaringWarningIncompleteNest(nest, appView);
    } else {
      appView.options().errorMissingClassIncompleteNest(nest, appView);
    }
  }
}
