// 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 com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.DexSourceCode;
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;
import java.util.function.Predicate;

public abstract class SyntheticSourceCode implements SourceCode {
  protected final static Predicate<IRBuilder> doesNotEndBlock = x -> false;
  protected final static Predicate<IRBuilder> endsBlock = x -> true;

  // TODO(b/146124603): Remove these fields as optimizations (e.g., merging) could invalidate them.
  protected final DexType receiver;
  protected final DexMethod method;
  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;

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

  private final Position position;

  protected SyntheticSourceCode(DexType receiver, DexMethod method, Position callerPosition) {
    this(receiver, method, callerPosition, method);
  }

  protected SyntheticSourceCode(
      DexType receiver, DexMethod method, Position callerPosition, DexMethod originalMethod) {
    assert method != null;
    this.receiver = receiver;
    this.method = method;
    this.proto = method.proto;

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

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

    position =
        SyntheticPosition.builder()
            .setLine(0)
            .setMethod(originalMethod)
            .setCallerPosition(callerPosition)
            .setIsD8R8Synthesized(true)
            .build();
  }

  protected final void add(Consumer<IRBuilder> constructor) {
    add(constructor, doesNotEndBlock);
  }

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

  protected final int nextRegister(ValueType type) {
    int value = nextRegister;
    nextRegister += type.requiredRegisters();
    return value;
  }

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

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

  protected abstract void prepareInstructions();

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

  protected final int lastInstructionIndex() {
    return constructors.size() - 1;
  }

  protected final int nextInstructionIndex() {
    return constructors.size();
  }

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

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

  @Override
  public DebugLocalInfo getIncomingLocalAtBlock(int register, int blockOffset) {
    return null;
  }

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

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

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

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

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

  @Override
  public final void buildPrelude(IRBuilder builder) {
    builder.buildArgumentsWithRewrittenPrototypeChanges(
        0, builder.getMethod(), DexSourceCode::doNothingWriteConsumer);
  }

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

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

  @Override
  public void buildBlockTransfer(
      IRBuilder builder, int predecessorOffset, int successorOffset, boolean isExceptional) {
    // Intentionally empty as synthetic code does not contain locals information.
  }

  @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(IRBuilder builder) {
    return null;
  }

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

  @Override
  public Position getCanonicalDebugPositionAtOffset(int offset) {
    return Position.syntheticNone();
  }

  @Override
  public Position getCurrentPosition() {
    return position;
  }

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

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

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

  // To be used as a tracing event for switch instruction.,
  protected boolean endsSwitch(
      IRBuilder builder, int switchIndex, int fallthrough, int[] offsets) {
    // ensure successors of switch instruction
    for (int offset : offsets) {
      builder.ensureNormalSuccessorBlock(switchIndex, offset);
    }
    builder.ensureNormalSuccessorBlock(switchIndex, fallthrough);
    return true;
  }
}
