// 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.graph.DexDebugEvent;
import com.android.tools.r8.graph.DexDebugInfo;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.utils.LebUtils;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class DebugBytecodeWriter {

  private final ObjectToOffsetMapping mapping;
  private final GraphLens graphLens;
  private final DexDebugInfo info;
  private ByteBuffer buffer;

  public DebugBytecodeWriter(
      DexDebugInfo info, ObjectToOffsetMapping mapping, GraphLens graphLens) {
    this.info = info;
    this.mapping = mapping;
    this.graphLens = graphLens;
    // Never allocate a zero-sized buffer, as we need to write the header, and the growth policy
    // requires it to have a positive capacity.
    this.buffer = ByteBuffer.allocate(info.events.length * 5 + 4);
  }

  public byte[] generate() {
    // Header.
    putUleb128(info.startLine); // line_start
    putUleb128(info.parameters.length);
    for (DexString name : info.parameters) {
      putString(name);
    }
    // Body.
    for (DexDebugEvent event : info.events) {
      event.writeOn(this, mapping, graphLens);
    }
    // Tail.
    putByte(Constants.DBG_END_SEQUENCE);
    return Arrays.copyOf(buffer.array(), buffer.position());
  }

  private void maybeGrow(int size) {
    if (buffer.remaining() < size) {
      ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() * 2);
      newBuffer.put(buffer.array(), 0, buffer.position());
      buffer = newBuffer;
    }
  }

  public void putByte(int item) {
    maybeGrow(1);
    buffer.put((byte) item);
  }

  public void putSleb128(int item) {
    byte[] encoded = LebUtils.encodeSleb128(item);
    maybeGrow(encoded.length);
    buffer.put(encoded, 0, encoded.length);
  }

  public void putUleb128(int item) {
    byte[] encoded = LebUtils.encodeUleb128(item);
    maybeGrow(encoded.length);
    buffer.put(encoded, 0, encoded.length);
  }

  private void putUleb128p1(int item) {
    putUleb128(item + 1);
  }

  private void putNoIndex() {
    putUleb128(0);
  }

  public void putType(DexType type) {
    if (type == null) {
      putNoIndex();
    } else {
      int index = mapping.getOffsetFor(type);
      putUleb128p1(index);
    }
  }

  public void putString(DexString string) {
    if (string == null) {
      putNoIndex();
    } else {
      int index = mapping.getOffsetFor(string);
      putUleb128p1(index);
    }
  }
}
