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

import it.unimi.dsi.fastutil.bytes.ByteIterator;
import java.util.Iterator;

/**
 * Basic iterator over the light IR.
 *
 * <p>This iterator is internally a zero-allocation parser with the "elements" as a view onto the
 * current state.
 */
public class LirIterator implements Iterator<LirInstructionView>, LirInstructionView {

  private final ByteIterator iterator;

  // State of the byte offsets into the iterator.
  private int currentByteIndex = 0;
  private int endOfCurrentInstruction = 0;

  // State of the instruction interpretation.
  private int currentInstructionIndex = -1;
  private int currentOpcode = -1;

  public LirIterator(ByteIterator iterator) {
    this.iterator = iterator;
  }

  private void skipRemainingOperands() {
    if (hasMoreOperands()) {
      skip(getRemainingOperandSizeInBytes());
    }
  }

  @Override
  public boolean hasNext() {
    skipRemainingOperands();
    return iterator.hasNext();
  }

  @Override
  public LirInstructionView next() {
    skipRemainingOperands();
    ++currentInstructionIndex;
    currentOpcode = u1();
    if (LirOpcodes.isOneByteInstruction(currentOpcode)) {
      endOfCurrentInstruction = currentByteIndex;
    } else {
      // Any instruction that is not a single byte has a two-byte header. The second byte is the
      // size of the variable width operand payload.
      int operandSize = u1();
      endOfCurrentInstruction = currentByteIndex + operandSize;
    }
    return this;
  }

  @Override
  public void accept(LirInstructionCallback eventCallback) {
    eventCallback.onInstructionView(this);
  }

  @Override
  public int getInstructionIndex() {
    return currentInstructionIndex;
  }

  @Override
  public int getOpcode() {
    return currentOpcode;
  }

  @Override
  public int getRemainingOperandSizeInBytes() {
    return endOfCurrentInstruction - currentByteIndex;
  }

  @Override
  public boolean hasMoreOperands() {
    return currentByteIndex < endOfCurrentInstruction;
  }

  @Override
  public int getNextIntegerOperand() {
    assert hasMoreOperands();
    return u4();
  }

  @Override
  public int getNextConstantOperand() {
    return getNextIntegerOperand();
  }

  @Override
  public int getNextValueOperand() {
    return getNextIntegerOperand();
  }

  @Override
  public int getNextBlockOperand() {
    return getNextIntegerOperand();
  }

  private void skip(int i) {
    currentByteIndex += i;
    iterator.skip(i);
  }

  private int u1() {
    ++currentByteIndex;
    return ByteUtils.fromU1(iterator.nextByte());
  }

  private int u4() {
    currentByteIndex += 4;
    return ByteUtils.readEncodedInt(iterator);
  }
}
