/* 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.parquet.column.values.boundedint;

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

import org.apache.parquet.io.ParquetDecodingException;

class BitReader {
  private int currentByte = 0;
  private int currentPosition = 8;
  private ByteBuffer buf;
  private int currentBufferPosition = 0;
  private static final int[] byteGetValueMask = new int[8];
  private static final int[] readMask = new int[32];
  private int endBufferPosistion;

  static {
    int currentMask = 1;
    for (int i = 0; i < byteGetValueMask.length; i++) {
      byteGetValueMask[i] = currentMask;
      currentMask <<= 1;
    }
    currentMask = 0;
    for (int i = 0; i < readMask.length; i++) {
      readMask[i] = currentMask;
      currentMask <<= 1;
      currentMask += 1;
    }
  }

  /**
   * Prepare to deserialize bit-packed integers from the given array.
   * The array is not copied, so must not be mutated during the course of
   * reading.
   */
  public void prepare(ByteBuffer buf, int offset, int length) {
    this.buf = buf;
    this.endBufferPosistion = offset + length;
    currentByte = 0;
    currentPosition = 8;
    currentBufferPosition = offset;
  }

  /**
   * Extract the given bit index from the given value.
   */
  private static boolean extractBit(int val, int bit) {
    return (val & byteGetValueMask[bit]) != 0;
  }

  /**
   * Read an integer from the stream which is represented by a specified
   * number of bits.
   * @param bitsPerValue the number of bits used to represent the integer
   */
  public int readNBitInteger(int bitsPerValue) {
    int bits = bitsPerValue + currentPosition;
    int currentValue = currentByte >>> currentPosition;
    int toShift = 8 - currentPosition;
    while (bits >= 8) {
      currentByte = getNextByte();
      currentValue |= currentByte << toShift;
      toShift += 8;
      bits -= 8;
    }
    currentValue &= readMask[bitsPerValue];
    currentPosition = (bitsPerValue + currentPosition) % 8;
    return currentValue;
  }

  private int getNextByte() {
    if (currentBufferPosition < endBufferPosistion) {
      return buf.get(currentBufferPosition++) & 0xFF;
    }
    return 0;
  }

  public boolean readBit() throws IOException {
    if (currentPosition == 8) {
      currentByte = getNextByte();
      currentPosition = 0;
    }
    return extractBit(currentByte, currentPosition++);
  }

  public int readByte() {
    currentByte |= (getNextByte() << 8);
    int value = (currentByte >>> currentPosition) & 0xFF;
    currentByte >>>= 8;
    return value;
  }

  public int readUnsignedVarint() throws IOException {
    int value = 0;
    int i = 0;
    int b;
    while (((b = readByte()) & 0x80) != 0) {
        value |= (b & 0x7F) << i;
        i += 7;
        if (i > 35) {
            throw new ParquetDecodingException("Variable length quantity is too long");
        }
    }
    return value | (b << i);
  }
}
