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

import static com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo.NO_THROW;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.MoveType;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.SourceCode;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public abstract class SingleBlockSourceCode implements SourceCode {

  protected final DexType receiver;
  protected final DexProto proto;

  // The next free register, note that we always
  // assign each value a new (next available) register.
  private int nextRegister = 0;

  // Registers for receiver and parameters
  private final int receiverRegister;
  private int[] paramRegisters;
  // Values representing receiver and parameters will be filled in
  // buildPrelude() and should only be accessed via appropriate methods
  private Value receiverValue;
  private Value[] paramValues;

  // Instruction constructors
  private List<Consumer<IRBuilder>> constructors = new ArrayList<>();

  protected SingleBlockSourceCode(DexType receiver, DexProto proto) {
    assert proto != null;
    this.receiver = receiver;
    this.proto = proto;

    // Initialize register values for receiver and arguments
    this.receiverRegister = receiver != null ? nextRegister(MoveType.OBJECT) : -1;

    DexType[] params = proto.parameters.values;
    int paramCount = params.length;
    this.paramRegisters = new int[paramCount];
    this.paramValues = new Value[paramCount];
    for (int i = 0; i < paramCount; i++) {
      this.paramRegisters[i] = nextRegister(MoveType.fromDexType(params[i]));
    }
  }

  protected final void add(Consumer<IRBuilder> constructor) {
    constructors.add(constructor);
  }

  protected final int nextRegister(MoveType type) {
    int value = nextRegister;
    nextRegister += type == MoveType.WIDE ? 2 : 1;
    return value;
  }

  protected final Value getReceiverValue() {
    assert receiver != null;
    assert receiverValue != null;
    return receiverValue;
  }

  protected final int getReceiverRegister() {
    assert receiver != null;
    assert receiverRegister >= 0;
    return receiverRegister;
  }

  protected final Value getParamValue(int paramIndex) {
    assert paramIndex >= 0;
    assert paramIndex < paramValues.length;
    return paramValues[paramIndex];
  }

  protected final int getParamCount() {
    return paramValues.length;
  }

  protected final int getParamRegister(int paramIndex) {
    assert paramIndex >= 0;
    assert paramIndex < paramRegisters.length;
    return paramRegisters[paramIndex];
  }

  protected abstract void prepareInstructions();

  @Override
  public final boolean needsPrelude() {
    return receiver != null || paramRegisters.length > 0;
  }

  @Override
  public final int instructionCount() {
    return constructors.size();
  }

  @Override
  public final int instructionIndex(int instructionOffset) {
    return instructionOffset;
  }

  @Override
  public final int instructionOffset(int instructionIndex) {
    return instructionIndex;
  }

  @Override
  public DebugLocalInfo getCurrentLocal(int register) {
    return null;
  }

  @Override
  public final int traceInstruction(int instructionIndex, IRBuilder builder) {
    return (instructionIndex == constructors.size() - 1) ? instructionIndex : -1;
  }

  @Override
  public final void closedCurrentBlockWithFallthrough(int fallthroughInstructionIndex) {
  }

  @Override
  public final void closedCurrentBlock() {
  }

  @Override
  public final void setUp() {
    assert constructors.isEmpty();
    prepareInstructions();
    assert !constructors.isEmpty();
  }

  @Override
  public final void clear() {
    constructors = null;
    paramRegisters = null;
    paramValues = null;
    receiverValue = null;
  }

  @Override
  public final void buildPrelude(IRBuilder builder) {
    if (receiver != null) {
      receiverValue = builder.writeRegister(receiverRegister, MoveType.OBJECT, NO_THROW);
      builder.add(new Argument(receiverValue));
      receiverValue.markAsThis();
    }

    // Fill in the Argument instructions in the argument block.
    DexType[] parameters = proto.parameters.values;
    for (int i = 0; i < parameters.length; i++) {
      MoveType moveType = MoveType.fromDexType(parameters[i]);
      Value paramValue = builder.writeRegister(paramRegisters[i], moveType, NO_THROW);
      paramValues[i] = paramValue;
      builder.add(new Argument(paramValue));
    }
  }

  @Override
  public final void buildPostlude(IRBuilder builder) {
    // Intentionally left empty.
  }

  @Override
  public final void buildInstruction(IRBuilder builder, int instructionIndex) {
    constructors.get(instructionIndex).accept(builder);
  }

  @Override
  public final void resolveAndBuildSwitch(
      int value, int fallthroughOffset, int payloadOffset, IRBuilder builder) {
    throw new Unreachable("Unexpected call to resolveAndBuildSwitch");
  }

  @Override
  public final void resolveAndBuildNewArrayFilledData(
      int arrayRef, int payloadOffset, IRBuilder builder) {
    throw new Unreachable("Unexpected call to resolveAndBuildNewArrayFilledData");
  }

  @Override
  public final CatchHandlers<Integer> getCurrentCatchHandlers() {
    return null;
  }

  @Override
  public final boolean verifyCurrentInstructionCanThrow() {
    return true;
  }

  @Override
  public boolean verifyLocalInScope(DebugLocalInfo local) {
    return true;
  }

  @Override
  public final boolean verifyRegister(int register) {
    return true;
  }
}
