// 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.optimize.enums.code;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxerImpl;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.IteratorUtils;

/**
 * A special code object used by enum unboxing that supplies IR from an existing method
 * checkNotNull() method. Minor rewritings are applied to the code after IR building to account for
 * enum unboxing.
 *
 * <p>Instances of {@link CheckNotZeroCode} are converted to {@link
 * com.android.tools.r8.graph.CfCode} or {@link com.android.tools.r8.graph.DexCode} immediately, and
 * thus should never be seen outside of the {@link EnumUnboxerImpl}.
 */
public class CheckNotZeroCode extends Code {

  // The checkNotNull() method to build IR from.
  private final ProgramMethod checkNotNullMethod;

  public CheckNotZeroCode(ProgramMethod checkNotNullMethod) {
    this.checkNotNullMethod = checkNotNullMethod;
  }

  @Override
  public IRCode buildIR(
      ProgramMethod checkNotZeroMethod,
      AppView<?> appView,
      Origin origin,
      MutableMethodConversionOptions conversionOptions) {
    // Build IR from the checkNotNull() method.
    IRCode code = checkNotNullMethod.buildIR(appView);
    InstructionListIterator instructionIterator = code.instructionListIterator();

    // Start iterating at the argument instruction for the checked argument.
    IteratorUtils.skip(
        instructionIterator,
        checkNotZeroMethod
            .getOptimizationInfo()
            .getEnumUnboxerMethodClassification()
            .asCheckNotNullClassification()
            .getArgumentIndex());

    // Rewrite the type of the argument instruction to int.
    Argument argument = instructionIterator.next().asArgument();
    instructionIterator.replaceCurrentInstruction(
        Argument.builder()
            .setFreshOutValue(code, TypeElement.getInt())
            .setIndex(argument.getIndex())
            .build());

    // Remove any assume instructions linked to the argument and replace all returns by return-void.
    while (instructionIterator.hasNext()) {
      Instruction instruction = instructionIterator.next();
      if (instruction.isAssume()) {
        instruction.outValue().replaceUsers(instruction.getFirstOperand());
        instructionIterator.removeOrReplaceByDebugLocalRead();
      } else if (instruction.isReturn() && instruction.asReturn().hasReturnValue()) {
        instructionIterator.replaceCurrentInstruction(new Return());
      }
    }

    // Transfer the IR to the given checkNotZero() method.
    return new IRCode(
        appView.options(),
        checkNotZeroMethod,
        code.getEntryPosition(),
        code.getBlocks(),
        code.valueNumberGenerator,
        code.basicBlockNumberGenerator,
        code.metadata(),
        checkNotZeroMethod.getOrigin(),
        conversionOptions);
  }

  @Override
  protected boolean computeEquals(Object other) {
    throw new Unreachable();
  }

  @Override
  protected int computeHashCode() {
    throw new Unreachable();
  }

  @Override
  public int estimatedDexCodeSizeUpperBoundInBytes() {
    throw new Unreachable();
  }

  @Override
  public boolean isEmptyVoidMethod() {
    throw new Unreachable();
  }

  @Override
  public void registerCodeReferences(ProgramMethod method, UseRegistry registry) {
    throw new Unreachable();
  }

  @Override
  public void registerCodeReferencesForDesugaring(ClasspathMethod method, UseRegistry registry) {
    throw new Unreachable();
  }

  @Override
  public String toString() {
    return "CheckNotZeroCode(" + checkNotNullMethod.toSourceString() + ")";
  }

  @Override
  public String toString(DexEncodedMethod method, ClassNameMapper naming) {
    return toString();
  }
}
