// Copyright (c) 2021, 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.icce;

import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.MethodResolutionResult;
import com.android.tools.r8.graph.MethodResolutionResult.FailedResolutionResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.DesugarDescription;
import com.android.tools.r8.ir.desugar.DesugarDescription.ScanCallback;
import com.android.tools.r8.ir.desugar.FreshLocalProvider;
import com.android.tools.r8.ir.desugar.LocalStackAllocator;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.MethodSynthesizerConsumer;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.UtilityMethodForCodeOptimizations;
import java.util.ArrayList;
import java.util.Collection;

public class AlwaysThrowingInstructionDesugaring implements CfInstructionDesugaring {

  private final AppView<? extends AppInfoWithClassHierarchy> appView;

  public AlwaysThrowingInstructionDesugaring(AppView<? extends AppInfoWithClassHierarchy> appView) {
    this.appView = appView;
  }

  @Override
  public Collection<CfInstruction> desugarInstruction(
      CfInstruction instruction,
      FreshLocalProvider freshLocalProvider,
      LocalStackAllocator localStackAllocator,
      CfInstructionDesugaringEventConsumer eventConsumer,
      ProgramMethod context,
      MethodProcessingContext methodProcessingContext,
      CfInstructionDesugaringCollection desugaringCollection,
      DexItemFactory dexItemFactory) {
    return computeDesugarDescription(instruction)
        .desugarInstruction(
            freshLocalProvider,
            localStackAllocator,
            eventConsumer,
            context,
            methodProcessingContext,
            dexItemFactory);
  }

  @Override
  public boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
    return computeDesugarDescription(instruction).needsDesugaring();
  }

  private DesugarDescription computeDesugarDescription(CfInstruction instruction) {
    if (instruction.isInvoke()) {
      CfInvoke invoke = instruction.asInvoke();
      DexMethod invokedMethod = invoke.getMethod();
      MethodResolutionResult resolutionResult =
          appView.appInfo().resolveMethod(invokedMethod, invoke.isInterface());
      if (shouldRewriteInvokeToThrow(invoke, resolutionResult)) {
        return computeInvokeAsThrowRewrite(appView, invoke, resolutionResult);
      }
    }
    return DesugarDescription.nothing();
  }

  private boolean shouldRewriteInvokeToThrow(
      CfInvoke invoke, MethodResolutionResult resolutionResult) {
    if (resolutionResult.isArrayCloneMethodResult()) {
      return false;
    }
    if (resolutionResult.isFailedResolution()) {
      // For now don't materialize NSMEs from failed resolutions.
      return resolutionResult.asFailedResolution().hasMethodsCausingError();
    }
    assert resolutionResult.isSingleResolution();
    return resolutionResult.getResolvedMethod().isStatic() != invoke.isInvokeStatic();
  }

  public static DesugarDescription computeInvokeAsThrowRewrite(
      AppView<?> appView, CfInvoke invoke, MethodResolutionResult resolutionResult) {
    return DesugarDescription.builder()
        .setDesugarRewrite(
            (freshLocalProvider,
                localStackAllocator,
                eventConsumer,
                context,
                methodProcessingContext,
                dexItemFactory) ->
                getThrowInstructions(
                    appView,
                    invoke,
                    localStackAllocator,
                    eventConsumer,
                    context,
                    methodProcessingContext,
                    getMethodSynthesizerForThrowing(appView, invoke, resolutionResult, context)))
        .build();
  }

  public static DesugarDescription computeInvokeAsThrowNSMERewrite(
      AppView<?> appView, CfInvoke invoke, ScanCallback scanCallback) {
    DesugarDescription.Builder builder =
        DesugarDescription.builder()
            .setDesugarRewrite(
                (freshLocalProvider,
                    localStackAllocator,
                    eventConsumer,
                    context,
                    methodProcessingContext,
                    dexItemFactory) ->
                    getThrowInstructions(
                        appView,
                        invoke,
                        localStackAllocator,
                        eventConsumer,
                        context,
                        methodProcessingContext,
                        UtilityMethodsForCodeOptimizations
                            ::synthesizeThrowNoSuchMethodErrorMethod));
    builder.addScanEffect(scanCallback);
    return builder.build();
  }

  private static Collection<CfInstruction> getThrowInstructions(
      AppView<?> appView,
      CfInvoke invoke,
      LocalStackAllocator localStackAllocator,
      CfInstructionDesugaringEventConsumer eventConsumer,
      ProgramMethod context,
      MethodProcessingContext methodProcessingContext,
      MethodSynthesizerConsumer methodSynthesizerConsumer) {
    if (methodSynthesizerConsumer == null) {
      assert false;
      return null;
    }

    // Replace the entire effect of the invoke by by call to the throwing helper:
    //   ...
    //   invoke <method> [receiver] args*
    // =>
    //   ...
    //   (pop arg)*
    //   [pop receiver]
    //   invoke <throwing-method>
    //   pop exception result
    //   [push fake result for <method>]
    UtilityMethodForCodeOptimizations throwMethod =
        methodSynthesizerConsumer.synthesizeMethod(appView, methodProcessingContext);
    ProgramMethod throwProgramMethod = throwMethod.uncheckedGetMethod();
    eventConsumer.acceptThrowMethod(throwProgramMethod, context);

    ArrayList<CfInstruction> replacement = new ArrayList<>();
    DexTypeList parameters = invoke.getMethod().getParameters();
    for (int i = parameters.values.length - 1; i >= 0; i--) {
      replacement.add(
          new CfStackInstruction(
              parameters.get(i).isWideType()
                  ? CfStackInstruction.Opcode.Pop2
                  : CfStackInstruction.Opcode.Pop));
    }
    if (!invoke.isInvokeStatic()) {
      replacement.add(new CfStackInstruction(CfStackInstruction.Opcode.Pop));
    }

    CfInvoke throwInvoke =
        new CfInvoke(
            org.objectweb.asm.Opcodes.INVOKESTATIC, throwProgramMethod.getReference(), false);
    assert throwInvoke.getMethod().getReturnType().isClassType();
    replacement.add(throwInvoke);
    replacement.add(new CfStackInstruction(CfStackInstruction.Opcode.Pop));

    DexType returnType = invoke.getMethod().getReturnType();
    if (!returnType.isVoidType()) {
      replacement.add(
          returnType.isPrimitiveType()
              ? new CfConstNumber(0, ValueType.fromDexType(returnType))
              : new CfConstNull());
    } else {
      // If the return type is void, the stack may need an extra slot to fit the return type of
      // the call to the throwing method.
      localStackAllocator.allocateLocalStack(1);
    }
    return replacement;
  }

  private static MethodSynthesizerConsumer getMethodSynthesizerForThrowing(
      AppView<?> appView,
      CfInvoke invoke,
      MethodResolutionResult resolutionResult,
      ProgramMethod context) {
    if (resolutionResult == null) {
      return UtilityMethodsForCodeOptimizations::synthesizeThrowNoSuchMethodErrorMethod;
    } else if (resolutionResult.isSingleResolution()) {
      if (resolutionResult.getResolvedMethod().isStatic() != invoke.isInvokeStatic()) {
        return UtilityMethodsForCodeOptimizations
            ::synthesizeThrowIncompatibleClassChangeErrorMethod;
      }
    } else if (resolutionResult.isFailedResolution()) {
      FailedResolutionResult failedResolutionResult = resolutionResult.asFailedResolution();
      AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
      if (failedResolutionResult.isIllegalAccessErrorResult(context.getHolder(), appInfo)) {
        return UtilityMethodsForCodeOptimizations::synthesizeThrowIllegalAccessErrorMethod;
      } else if (failedResolutionResult.isNoSuchMethodErrorResult(context.getHolder(), appInfo)) {
        return UtilityMethodsForCodeOptimizations::synthesizeThrowNoSuchMethodErrorMethod;
      } else if (failedResolutionResult.isIncompatibleClassChangeErrorResult()) {
        return UtilityMethodsForCodeOptimizations
            ::synthesizeThrowIncompatibleClassChangeErrorMethod;
      }
    }

    return null;
  }
}
