// Copyright (c) 2023, 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.optimize.numberunboxer;

import com.android.tools.r8.graph.AppView;
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.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.fixup.ConcurrentMethodFixup;
import com.android.tools.r8.graph.fixup.ConcurrentMethodFixup.ProgramClassFixer;
import com.android.tools.r8.graph.fixup.MethodNamingUtility;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.optimize.numberunboxer.NumberUnboxerBoxingStatusResolution.MethodBoxingStatusResult;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.ArrayUtils;
import com.android.tools.r8.utils.OptionalBool;
import com.android.tools.r8.utils.Timing;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

public class NumberUnboxerTreeFixer implements ProgramClassFixer {

  private final AppView<AppInfoWithLiveness> appView;
  private final Map<DexMethod, MethodBoxingStatusResult> unboxingResult;
  private final Map<DexMethod, DexMethod> virtualMethodsRepresentative;

  private final NumberUnboxerLens.Builder lensBuilder = NumberUnboxerLens.builder();

  public NumberUnboxerTreeFixer(
      AppView<AppInfoWithLiveness> appView,
      Map<DexMethod, MethodBoxingStatusResult> unboxingResult,
      Map<DexMethod, DexMethod> virtualMethodsRepresentative) {
    this.appView = appView;
    this.unboxingResult = unboxingResult;
    this.virtualMethodsRepresentative = virtualMethodsRepresentative;
  }

  public NumberUnboxerLens fixupTree(ExecutorService executorService, Timing timing)
      throws ExecutionException {
    // Take strongly connected components, for each merge data from call-sites and methods and
    // unbox.
    new ConcurrentMethodFixup(appView, this)
        .fixupClassesConcurrentlyByConnectedProgramComponents(timing, executorService);
    return lensBuilder.build(appView, new NumberUnboxerRewriter(appView));
  }

  @Override
  public void fixupProgramClass(DexProgramClass clazz, MethodNamingUtility utility) {
    clazz.getMethodCollection().replaceMethods(m -> fixupEncodedMethod(m, utility));
  }

  @Override
  public boolean shouldReserveAsIfPinned(ProgramMethod method) {
    // We don't reprocess dependencies of unchanged methods so we have to maintain them
    // with the same signature.
    return !unboxingResult.containsKey(representative(method.getReference()));
  }

  private DexMethod representative(DexMethod method) {
    return virtualMethodsRepresentative.getOrDefault(method, method);
  }

  private DexEncodedMethod fixupEncodedMethod(
      DexEncodedMethod method, MethodNamingUtility utility) {
    if (!unboxingResult.containsKey(representative(method.getReference()))) {
      assert method
          .getReference()
          .isIdenticalTo(
              utility.nextUniqueMethod(
                  method, method.getProto(), appView.dexItemFactory().shortType));
      return method;
    }
    MethodBoxingStatusResult methodBoxingStatus =
        unboxingResult.get(representative(method.getReference()));
    assert !methodBoxingStatus.isNoneUnboxable();
    DexProto newProto = fixupProto(method.getProto(), methodBoxingStatus);
    DexMethod newMethod =
        utility.nextUniqueMethod(method, newProto, appView.dexItemFactory().shortType);

    RewrittenPrototypeDescription prototypeChanges = lensBuilder.move(method, newMethod);
    return method.toTypeSubstitutedMethodAsInlining(
        newMethod,
        appView.dexItemFactory(),
        builder ->
            builder
                .fixupOptimizationInfo(
                    appView, prototypeChanges.createMethodOptimizationInfoFixer())
                .setCompilationState(method.getCompilationState())
                .setIsLibraryMethodOverrideIf(
                    method.isNonPrivateVirtualMethod(), OptionalBool.FALSE));
  }

  private DexType fixupType(DexType type, boolean unbox) {
    if (!unbox) {
      return type;
    }
    DexType newType = appView.dexItemFactory().primitiveToBoxed.inverse().get(type);
    assert newType != null;
    return newType;
  }

  private DexProto fixupProto(DexProto proto, MethodBoxingStatusResult methodBoxingStatus) {
    DexType[] argTypes = proto.getParameters().values;
    DexType[] newArgTypes =
        ArrayUtils.initialize(
            new DexType[argTypes.length],
            i -> fixupType(argTypes[i], methodBoxingStatus.shouldUnboxArg(i)));
    DexType newReturnType = fixupType(proto.getReturnType(), methodBoxingStatus.shouldUnboxRet());
    DexProto newProto = appView.dexItemFactory().createProto(newReturnType, newArgTypes);
    assert newProto.isNotIdenticalTo(proto);
    return newProto;
  }
}
