// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;

/**
 * Common methods to encode and decode varints and varlongs into ByteBuffers and
 * arrays.
 */
public class VarInt {

  /**
   * Maximum encoded size of 32-bit positive integers (in bytes)
   */
  public static final int MAX_VARINT_SIZE = 5;

  /**
   * maximum encoded size of 64-bit longs, and negative 32-bit ints (in bytes)
   */
  public static final int MAX_VARLONG_SIZE = 10;

  private VarInt() { }

  /** Returns the encoding size in bytes of its input value.
   * @param i the integer to be measured
   * @return the encoding size in bytes of its input value
   */
  public static int varIntSize(int i) {
    int result = 0;
    do {
      result++;
      i >>>= 7;
    } while (i != 0);
    return result;
  }

  /**
   * Reads a varint  from src, places its values into the first element of
   * dst and returns the offset in to src of the first byte after the varint.
   *
   * @param src source buffer to retrieve from
   * @param offset offset within src
   * @param dst the resulting int value
   * @return the updated offset after reading the varint
   */
  public static int getVarInt(byte[] src, int offset, int[] dst) {
    int result = 0;
    int shift = 0;
    int b;
    do {
      if (shift >= 32) {
        // Out of range
        throw new IndexOutOfBoundsException("varint too long");
      }
      // Get 7 bits from next byte
      b = src[offset++];
      result |= (b & 0x7F) << shift;
      shift += 7;
    } while ((b & 0x80) != 0);
    dst[0] = result;
    return offset;
  }

  /**
   * Encodes an integer in a variable-length encoding, 7 bits per byte, into a
   * destination byte[], following the protocol buffer convention.
   *
   * @param v the int value to write to sink
   * @param sink the sink buffer to write to
   * @param offset the offset within sink to begin writing
   * @return the updated offset after writing the varint
   */
  public static int putVarInt(int v, byte[] sink, int offset) {
    do {
      // Encode next 7 bits + terminator bit
      int bits = v & 0x7F;
      v >>>= 7;
      byte b = (byte) (bits + ((v != 0) ? 0x80 : 0));
      sink[offset++] = b;
    } while (v != 0);
    return offset;
  }

  /**
   * Reads a varint from the current position of the given ByteBuffer and
   * returns the decoded value as 32 bit integer.
   *
   * <p>The position of the buffer is advanced to the first byte after the
   * decoded varint.
   *
   * @param src the ByteBuffer to get the var int from
   * @return The integer value of the decoded varint
   */
  public static int getVarInt(ByteBuffer src) {
    int tmp;
    if ((tmp = src.get()) >= 0) {
      return tmp;
    }
    int result = tmp & 0x7f;
    if ((tmp = src.get()) >= 0) {
      result |= tmp << 7;
    } else {
      result |= (tmp & 0x7f) << 7;
      if ((tmp = src.get()) >= 0) {
        result |= tmp << 14;
      } else {
        result |= (tmp & 0x7f) << 14;
        if ((tmp = src.get()) >= 0) {
          result |= tmp << 21;
        } else {
          result |= (tmp & 0x7f) << 21;
          result |= (tmp = src.get()) << 28;
          while (tmp < 0) {
            // We get into this loop only in the case of overflow.
            // By doing this, we can call getVarInt() instead of
            // getVarLong() when we only need an int.
            tmp = src.get();
          }
        }
      }
    }
    return result;
  }

  /**
   * Encodes an integer in a variable-length encoding, 7 bits per byte, to a
   * ByteBuffer sink.
   * @param v the value to encode
   * @param sink the ByteBuffer to add the encoded value
   */
  public static void putVarInt(int v, ByteBuffer sink) {
    while (true) {
      int bits = v & 0x7f;
      v >>>= 7;
      if (v == 0) {
        sink.put((byte) bits);
        return;
      }
      sink.put((byte) (bits | 0x80));
    }
  }

  /**
   * Reads a varint from the given InputStream and returns the decoded value
   * as an int.
   *
   * @param inputStream the InputStream to read from
   */
  public static int getVarInt(InputStream inputStream) throws IOException {
    int result = 0;
    int shift = 0;
    int b;
    do {
      if (shift >= 32) {
        // Out of range
        throw new IndexOutOfBoundsException("varint too long");
      }
      // Get 7 bits from next byte
      b = inputStream.read();
      result |= (b & 0x7F) << shift;
      shift += 7;
    } while ((b & 0x80) != 0);
    return result;
  }

  /**
   * Encodes an integer in a variable-length encoding, 7 bits per byte, and
   * writes it to the given OutputStream.
   *
   * @param v the value to encode
   * @param outputStream the OutputStream to write to
   */
  public static void putVarInt(int v, OutputStream outputStream) throws IOException {
    byte[] bytes = new byte[varIntSize(v)];
    putVarInt(v, bytes, 0);
    outputStream.write(bytes);
  }

  /**
   * Returns the encoding size in bytes of its input value.
   *
   * @param v the long to be measured
   * @return the encoding size in bytes of a given long value.
   */
  public static int varLongSize(long v) {
    int result = 0;
    do {
      result++;
      v >>>= 7;
    } while (v != 0);
    return result;
  }

  /**
   * Reads an up to 64 bit long varint from the current position of the
   * given ByteBuffer and returns the decoded value as long.
   *
   * <p>The position of the buffer is advanced to the first byte after the
   * decoded varint.
   *
   * @param src the ByteBuffer to get the var int from
   * @return The integer value of the decoded long varint
   */
  public static long getVarLong(ByteBuffer src) {
    long tmp;
    if ((tmp = src.get()) >= 0) {
      return tmp;
    }
    long result = tmp & 0x7f;
    if ((tmp = src.get()) >= 0) {
      result |= tmp << 7;
    } else {
      result |= (tmp & 0x7f) << 7;
      if ((tmp = src.get()) >= 0) {
        result |= tmp << 14;
      } else {
        result |= (tmp & 0x7f) << 14;
        if ((tmp = src.get()) >= 0) {
          result |= tmp << 21;
        } else {
          result |= (tmp & 0x7f) << 21;
          if ((tmp = src.get()) >= 0) {
            result |= tmp << 28;
          } else {
            result |= (tmp & 0x7f) << 28;
            if ((tmp = src.get()) >= 0) {
              result |= tmp << 35;
            } else {
              result |= (tmp & 0x7f) << 35;
              if ((tmp = src.get()) >= 0) {
                result |= tmp << 42;
              } else {
                result |= (tmp & 0x7f) << 42;
                if ((tmp = src.get()) >= 0) {
                  result |= tmp << 49;
                } else {
                  result |= (tmp & 0x7f) << 49;
                  if ((tmp = src.get()) >= 0) {
                    result |= tmp << 56;
                  } else {
                    result |= (tmp & 0x7f) << 56;
                    result |= ((long) src.get()) << 63;
                  }
                }
              }
            }
          }
        }
      }
    }
    return result;
  }

  /**
   * Encodes a long integer in a variable-length encoding, 7 bits per byte, to a
   * ByteBuffer sink.
   * @param v the value to encode
   * @param sink the ByteBuffer to add the encoded value
   */
  public static void putVarLong(long v, ByteBuffer sink) {
    while (true) {
      int bits = ((int) v) & 0x7f;
      v >>>= 7;
      if (v == 0) {
        sink.put((byte) bits);
        return;
      }
      sink.put((byte) (bits | 0x80));
    }
  }
}
