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

import com.android.tools.r8.ByteBufferProvider;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexWritableCode;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.utils.EncodedValueUtils;
import com.android.tools.r8.utils.LebUtils;
import com.google.common.annotations.VisibleForTesting;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;

/**
 * Provides an abstraction around a {@link ByteBuffer} with write operations for
 * additional DEX specific formats, like Leb128.
 */
public class DexOutputBuffer {
  private static final int DEFAULT_BUFFER_SIZE = 256 * 1024;

  private final ByteBufferProvider byteBufferProvider;
  private CompatByteBuffer byteBuffer;

  @VisibleForTesting
  DexOutputBuffer() {
    this(new ByteBufferProvider() {});
  }

  public DexOutputBuffer(ByteBufferProvider byteBufferProvider) {
    this.byteBufferProvider = byteBufferProvider;
    byteBuffer = allocateByteBuffer(DEFAULT_BUFFER_SIZE);
  }

  private void ensureSpaceFor(int bytes) {
    if (byteBuffer.remaining() < bytes) {
      int newSize = byteBuffer.capacity() + Math.max(byteBuffer.capacity(), bytes * 2);
      CompatByteBuffer newBuffer = allocateByteBuffer(newSize);
      System.arraycopy(byteBuffer.array(), 0, newBuffer.array(), 0, byteBuffer.capacity());
      newBuffer.position(byteBuffer.position());
      freeByteBuffer(byteBuffer);
      byteBuffer = newBuffer;
    }
  }

  private CompatByteBuffer allocateByteBuffer(int size) {
    CompatByteBuffer buffer = new CompatByteBuffer(byteBufferProvider.acquireByteBuffer(size));
    if (!buffer.hasArray()) {
      throw new CompilationError(
          "Provided byte-buffer is required to have an array backing, but does not.");
    }
    if (buffer.capacity() < size) {
      throw new CompilationError(
          "Insufficient capacity of provided byte-buffer."
              + " Requested capacity "
              + size
              + ", actual capacity: "
              + buffer.capacity());
    }
    if (buffer.position() != 0) {
      throw new CompilationError(
          "Provided byte-buffer is required to start at position zero, but starts at "
              + buffer.position()
              + ".");
    }
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    return buffer;
  }

  private void freeByteBuffer(CompatByteBuffer buffer) {
    assert buffer != null;
    byteBufferProvider.releaseByteBuffer(buffer.asByteBuffer());
  }

  public void putUleb128(int value) {
    LebUtils.putUleb128(this, value);
  }

  public void putSleb128(int value) {
    LebUtils.putSleb128(this, value);
  }

  public int putSignedEncodedValue(long value, int expectedSize) {
    return EncodedValueUtils.putSigned(this, value, expectedSize);
  }

  public int putUnsignedEncodedValue(long value, int expectedSize) {
    return EncodedValueUtils.putUnsigned(this, value, expectedSize);
  }

  public void putInstructions(
      AppView<?> appView,
      DexWritableCode code,
      ProgramMethod context,
      ObjectToOffsetMapping mapping,
      CodeToKeep desugaredLibraryCodeToKeep) {
    int size = code.codeSizeInBytes();
    ensureSpaceFor(size * Short.BYTES);
    assert byteBuffer.position() % 2 == 0;
    ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
    code.writeDex(
        shortBuffer,
        context,
        mapping.getGraphLens(),
        code.getCodeLens(appView),
        mapping.getLensCodeRewriter(),
        mapping);
    code.writeKeepRulesForDesugaredLibrary(desugaredLibraryCodeToKeep);
    byteBuffer.position(byteBuffer.position() + shortBuffer.position() * Short.BYTES);
  }

  public void putByte(byte aByte) {
    ensureSpaceFor(Byte.BYTES);
    byteBuffer.put(aByte);
  }

  public void putBytes(byte[] bytes) {
    ensureSpaceFor(bytes.length);
    byteBuffer.put(bytes);
  }

  public void putShort(short aShort) {
    ensureSpaceFor(Short.BYTES);
    byteBuffer.putShort(aShort);
  }

  public void putInt(int anInteger) {
    ensureSpaceFor(Integer.BYTES);
    byteBuffer.putInt(anInteger);
  }

  public short getShort() {
    return byteBuffer.getShort();
  }

  public int getInt() {
    return byteBuffer.getInt();
  }

  public boolean assertZero() {
    int pos = byteBuffer.position();
    int i = byteBuffer.getInt();
    assert i == 0;
    byteBuffer.position(pos);
    return true;
  }

  /**
   * Moves the position in the bytebuffer forward until it is aligned.
   *
   * @param bytes  alignment requirement in bytes
   * @return       the new position after alignment
   */
  public int align(int bytes) {
    assert bytes > 0;
    int mask = bytes - 1;
    int newPosition = (position() + mask) & ~mask;
    ensureSpaceFor(newPosition - position());
    byteBuffer.position(newPosition);
    return newPosition;
  }

  public int position() {
    return byteBuffer.position();
  }

  public void forward(int bytes) {
    ensureSpaceFor(bytes);
    byteBuffer.position(byteBuffer.position() + bytes);
  }

  public void rewind(int bytes) {
    forward(-bytes);
  }

  public void moveTo(int position) {
    ensureSpaceFor(position - byteBuffer.position());
    byteBuffer.position(position);
  }

  public boolean isAligned(int bytes) {
    return position() % bytes == 0;
  }

  public byte[] asArray() {
    return byteBuffer.array();
  }

  public CompatByteBuffer stealByteBuffer() {
    CompatByteBuffer buffer = byteBuffer;
    byteBuffer = null;
    return buffer;
  }
}
