// 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.utils;

import com.android.tools.r8.dex.BinaryReader;
import com.android.tools.r8.dex.DexOutputBuffer;
import java.util.Arrays;

public class LebUtils {
  private static final int BITS_PER_ENCODED_BYTE = 7;
  private static final int PAYLOAD_MASK = 0x7f;
  private static final int MORE_DATA_TAG_BIT = 0x80;
  private static final int MAX_BYTES_PER_VALUE = 5;

  public static int parseUleb128(BinaryReader reader) {
    int result = 0;
    byte b;
    int shift = 0;
    do {
      b = reader.get();
      result |= (b & (byte) PAYLOAD_MASK) << shift;
      shift += BITS_PER_ENCODED_BYTE;
    } while ((b & ~(byte) PAYLOAD_MASK) == ~(byte) PAYLOAD_MASK);
    assert shift <= MAX_BYTES_PER_VALUE * BITS_PER_ENCODED_BYTE;  // At most five bytes are used.
    assert result >= 0;  // Ensure the java int didn't overflow.
    return result;
  }

  // Inspired by com.android.dex.Leb128.java
  public static byte[] encodeUleb128(int value) {
    byte result[] = new byte[MAX_BYTES_PER_VALUE];
    int remaining = value >>> BITS_PER_ENCODED_BYTE;
    int bytes = 0;
    while (remaining != 0) {
      result[bytes++] = (byte) ((value & PAYLOAD_MASK) | MORE_DATA_TAG_BIT);
      value = remaining;
      remaining >>>= BITS_PER_ENCODED_BYTE;
    }
    result[bytes++] = (byte) (value & PAYLOAD_MASK);
    return Arrays.copyOf(result, bytes);
  }

  // Inspired by com.android.dex.Leb128.java
  public static void putUleb128(DexOutputBuffer outputBuffer, int value) {
    int remaining = value >>> BITS_PER_ENCODED_BYTE;
    while (remaining != 0) {
      outputBuffer.putByte((byte) ((value & PAYLOAD_MASK) | MORE_DATA_TAG_BIT));
      value = remaining;
      remaining >>>= BITS_PER_ENCODED_BYTE;
    }
    outputBuffer.putByte((byte) (value & PAYLOAD_MASK));
  }

  public static int sizeAsUleb128(int value) {
    return Math
        .max(1, (Integer.SIZE - Integer.numberOfLeadingZeros(value) + 6) / BITS_PER_ENCODED_BYTE);
  }

  public static int parseSleb128(BinaryReader reader) {
    int result = 0;
    byte b;
    int shift = 0;
    do {
      b = reader.get();
      result |= (b & (byte) PAYLOAD_MASK) << shift;
      shift += BITS_PER_ENCODED_BYTE;
    } while ((b & ~(byte) PAYLOAD_MASK) == ~(byte) PAYLOAD_MASK);
    int mask = 1 << (shift - 1);
    assert shift <= MAX_BYTES_PER_VALUE * BITS_PER_ENCODED_BYTE;  // At most five bytes are used.
    return (result ^ mask) - mask;
  }

  // Inspired by com.android.dex.Leb128.java
  public static byte[] encodeSleb128(int value) {
    byte result[] = new byte[MAX_BYTES_PER_VALUE];
    int remaining = value >> BITS_PER_ENCODED_BYTE;
    boolean hasMore = true;
    int end = value >= 0 ? 0 : -1;
    int bytes = 0;
    while (hasMore) {
      hasMore = (remaining != end)
          || ((remaining & 1) != ((value >> 6) & 1));
      result[bytes++] = (byte) ((value & PAYLOAD_MASK) | (hasMore ? MORE_DATA_TAG_BIT : 0));
      value = remaining;
      remaining >>= BITS_PER_ENCODED_BYTE;
    }
    return Arrays.copyOf(result, bytes);
  }

  // Inspired by com.android.dex.Leb128.java
  public static void putSleb128(DexOutputBuffer outputBuffer, int value) {
    int remaining = value >> BITS_PER_ENCODED_BYTE;
    boolean hasMore = true;
    int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
    while (hasMore) {
      hasMore = (remaining != end)
          || ((remaining & 1) != ((value >> 6) & 1));
      outputBuffer.putByte((byte) ((value & PAYLOAD_MASK) | (hasMore ? MORE_DATA_TAG_BIT : 0)));
      value = remaining;
      remaining >>= BITS_PER_ENCODED_BYTE;
    }
  }

  public static int sizeAsSleb128(int value) {
    if (value < 0) {
      value = ~value;
    }
    // Note the + 7 to account for the extra bit on 7-bit boundaries.
    return (Integer.SIZE - Integer.numberOfLeadingZeros(value) + 7) / BITS_PER_ENCODED_BYTE;
  }

  public static byte[] encodeUleb128p1(int value) {
    return encodeUleb128(value + 1);
  }

  public static byte[][] encodeUleb128p1(int[] values) {
    byte[][] result = new byte[values.length][];
    for (int i = 0; i < result.length; i++) {
      result[i] = encodeUleb128p1(values[i]);
    }
    return result;
  }
}
