// Copyright (c) 2017 Google Inc.
//
// 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.

#include <algorithm>
#include <cassert>
#include <cstring>
#include <sstream>
#include <type_traits>

#include "source/util/bit_stream.h"

namespace spvtools {
namespace utils {
namespace {

// Returns if the system is little-endian. Unfortunately only works during
// runtime.
bool IsLittleEndian() {
  // This constant value allows the detection of the host machine's endianness.
  // Accessing it as an array of bytes is valid due to C++11 section 3.10
  // paragraph 10.
  static const uint16_t kFF00 = 0xff00;
  return reinterpret_cast<const unsigned char*>(&kFF00)[0] == 0;
}

// Copies bytes from the given buffer to a uint64_t buffer.
// Motivation: casting uint64_t* to uint8_t* is ok. Casting in the other
// direction is only advisable if uint8_t* is aligned to 64-bit word boundary.
std::vector<uint64_t> ToBuffer64(const void* buffer, size_t num_bytes) {
  std::vector<uint64_t> out;
  out.resize((num_bytes + 7) / 8, 0);
  memcpy(out.data(), buffer, num_bytes);
  return out;
}

// Copies uint8_t buffer to a uint64_t buffer.
std::vector<uint64_t> ToBuffer64(const std::vector<uint8_t>& in) {
  return ToBuffer64(in.data(), in.size());
}

// Returns uint64_t containing the same bits as |val|.
// Type size must be less than 8 bytes.
template <typename T>
uint64_t ToU64(T val) {
  static_assert(sizeof(T) <= 8, "Type size too big");
  uint64_t val64 = 0;
  std::memcpy(&val64, &val, sizeof(T));
  return val64;
}

// Returns value of type T containing the same bits as |val64|.
// Type size must be less than 8 bytes. Upper (unused) bits of |val64| must be
// zero (irrelevant, but is checked with assertion).
template <typename T>
T FromU64(uint64_t val64) {
  assert(sizeof(T) == 8 || (val64 >> (sizeof(T) * 8)) == 0);
  static_assert(sizeof(T) <= 8, "Type size too big");
  T val = 0;
  std::memcpy(&val, &val64, sizeof(T));
  return val;
}

// Writes bits from |val| to |writer| in chunks of size |chunk_length|.
// Signal bit is used to signal if the reader should expect another chunk:
// 0 - no more chunks to follow
// 1 - more chunks to follow
// If number of written bits reaches |max_payload| last chunk is truncated.
void WriteVariableWidthInternal(BitWriterInterface* writer, uint64_t val,
                                size_t chunk_length, size_t max_payload) {
  assert(chunk_length > 0);
  assert(chunk_length < max_payload);
  assert(max_payload == 64 || (val >> max_payload) == 0);

  if (val == 0) {
    // Split in two writes for more readable logging.
    writer->WriteBits(0, chunk_length);
    writer->WriteBits(0, 1);
    return;
  }

  size_t payload_written = 0;

  while (val) {
    if (payload_written + chunk_length >= max_payload) {
      // This has to be the last chunk.
      // There is no need for the signal bit and the chunk can be truncated.
      const size_t left_to_write = max_payload - payload_written;
      assert((val >> left_to_write) == 0);
      writer->WriteBits(val, left_to_write);
      break;
    }

    writer->WriteBits(val, chunk_length);
    payload_written += chunk_length;
    val = val >> chunk_length;

    // Write a single bit to signal if there is more to come.
    writer->WriteBits(val ? 1 : 0, 1);
  }
}

// Reads data written with WriteVariableWidthInternal. |chunk_length| and
// |max_payload| should be identical to those used to write the data.
// Returns false if the stream ends prematurely.
bool ReadVariableWidthInternal(BitReaderInterface* reader, uint64_t* val,
                               size_t chunk_length, size_t max_payload) {
  assert(chunk_length > 0);
  assert(chunk_length <= max_payload);
  size_t payload_read = 0;

  while (payload_read + chunk_length < max_payload) {
    uint64_t bits = 0;
    if (reader->ReadBits(&bits, chunk_length) != chunk_length) return false;

    *val |= bits << payload_read;
    payload_read += chunk_length;

    uint64_t more_to_come = 0;
    if (reader->ReadBits(&more_to_come, 1) != 1) return false;

    if (!more_to_come) {
      return true;
    }
  }

  // Need to read the last chunk which may be truncated. No signal bit follows.
  uint64_t bits = 0;
  const size_t left_to_read = max_payload - payload_read;
  if (reader->ReadBits(&bits, left_to_read) != left_to_read) return false;

  *val |= bits << payload_read;
  return true;
}

// Calls WriteVariableWidthInternal with the right max_payload argument.
template <typename T>
void WriteVariableWidthUnsigned(BitWriterInterface* writer, T val,
                                size_t chunk_length) {
  static_assert(std::is_unsigned<T>::value, "Type must be unsigned");
  static_assert(std::is_integral<T>::value, "Type must be integral");
  WriteVariableWidthInternal(writer, val, chunk_length, sizeof(T) * 8);
}

// Calls ReadVariableWidthInternal with the right max_payload argument.
template <typename T>
bool ReadVariableWidthUnsigned(BitReaderInterface* reader, T* val,
                               size_t chunk_length) {
  static_assert(std::is_unsigned<T>::value, "Type must be unsigned");
  static_assert(std::is_integral<T>::value, "Type must be integral");
  uint64_t val64 = 0;
  if (!ReadVariableWidthInternal(reader, &val64, chunk_length, sizeof(T) * 8))
    return false;
  *val = static_cast<T>(val64);
  assert(*val == val64);
  return true;
}

// Encodes signed |val| to an unsigned value and calls
// WriteVariableWidthInternal with the right max_payload argument.
template <typename T>
void WriteVariableWidthSigned(BitWriterInterface* writer, T val,
                              size_t chunk_length, size_t zigzag_exponent) {
  static_assert(std::is_signed<T>::value, "Type must be signed");
  static_assert(std::is_integral<T>::value, "Type must be integral");
  WriteVariableWidthInternal(writer, EncodeZigZag(val, zigzag_exponent),
                             chunk_length, sizeof(T) * 8);
}

// Calls ReadVariableWidthInternal with the right max_payload argument
// and decodes the value.
template <typename T>
bool ReadVariableWidthSigned(BitReaderInterface* reader, T* val,
                             size_t chunk_length, size_t zigzag_exponent) {
  static_assert(std::is_signed<T>::value, "Type must be signed");
  static_assert(std::is_integral<T>::value, "Type must be integral");
  uint64_t encoded = 0;
  if (!ReadVariableWidthInternal(reader, &encoded, chunk_length, sizeof(T) * 8))
    return false;

  const int64_t decoded = DecodeZigZag(encoded, zigzag_exponent);

  *val = static_cast<T>(decoded);
  assert(*val == decoded);
  return true;
}

}  // namespace

void BitWriterInterface::WriteVariableWidthU64(uint64_t val,
                                               size_t chunk_length) {
  WriteVariableWidthUnsigned(this, val, chunk_length);
}

void BitWriterInterface::WriteVariableWidthU32(uint32_t val,
                                               size_t chunk_length) {
  WriteVariableWidthUnsigned(this, val, chunk_length);
}

void BitWriterInterface::WriteVariableWidthU16(uint16_t val,
                                               size_t chunk_length) {
  WriteVariableWidthUnsigned(this, val, chunk_length);
}

void BitWriterInterface::WriteVariableWidthS64(int64_t val, size_t chunk_length,
                                               size_t zigzag_exponent) {
  WriteVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
}

BitWriterWord64::BitWriterWord64(size_t reserve_bits) : end_(0) {
  buffer_.reserve(NumBitsToNumWords<64>(reserve_bits));
}

void BitWriterWord64::WriteBits(uint64_t bits, size_t num_bits) {
  // Check that |bits| and |num_bits| are valid and consistent.
  assert(num_bits <= 64);
  const bool is_little_endian = IsLittleEndian();
  assert(is_little_endian && "Big-endian architecture support not implemented");
  if (!is_little_endian) return;

  if (num_bits == 0) return;

  bits = GetLowerBits(bits, num_bits);

  EmitSequence(bits, num_bits);

  // Offset from the start of the current word.
  const size_t offset = end_ % 64;

  if (offset == 0) {
    // If no offset, simply add |bits| as a new word to the buffer_.
    buffer_.push_back(bits);
  } else {
    // Shift bits and add them to the current word after offset.
    const uint64_t first_word = bits << offset;
    buffer_.back() |= first_word;

    // If we don't overflow to the next word, there is nothing more to do.

    if (offset + num_bits > 64) {
      // We overflow to the next word.
      const uint64_t second_word = bits >> (64 - offset);
      // Add remaining bits as a new word to buffer_.
      buffer_.push_back(second_word);
    }
  }

  // Move end_ into position for next write.
  end_ += num_bits;
  assert(buffer_.size() * 64 >= end_);
}

bool BitReaderInterface::ReadVariableWidthU64(uint64_t* val,
                                              size_t chunk_length) {
  return ReadVariableWidthUnsigned(this, val, chunk_length);
}

bool BitReaderInterface::ReadVariableWidthU32(uint32_t* val,
                                              size_t chunk_length) {
  return ReadVariableWidthUnsigned(this, val, chunk_length);
}

bool BitReaderInterface::ReadVariableWidthU16(uint16_t* val,
                                              size_t chunk_length) {
  return ReadVariableWidthUnsigned(this, val, chunk_length);
}

bool BitReaderInterface::ReadVariableWidthS64(int64_t* val, size_t chunk_length,
                                              size_t zigzag_exponent) {
  return ReadVariableWidthSigned(this, val, chunk_length, zigzag_exponent);
}

BitReaderWord64::BitReaderWord64(std::vector<uint64_t>&& buffer)
    : buffer_(std::move(buffer)), pos_(0) {}

BitReaderWord64::BitReaderWord64(const std::vector<uint8_t>& buffer)
    : buffer_(ToBuffer64(buffer)), pos_(0) {}

BitReaderWord64::BitReaderWord64(const void* buffer, size_t num_bytes)
    : buffer_(ToBuffer64(buffer, num_bytes)), pos_(0) {}

size_t BitReaderWord64::ReadBits(uint64_t* bits, size_t num_bits) {
  assert(num_bits <= 64);
  const bool is_little_endian = IsLittleEndian();
  assert(is_little_endian && "Big-endian architecture support not implemented");
  if (!is_little_endian) return 0;

  if (ReachedEnd()) return 0;

  // Index of the current word.
  const size_t index = pos_ / 64;

  // Bit position in the current word where we start reading.
  const size_t offset = pos_ % 64;

  // Read all bits from the current word (it might be too much, but
  // excessive bits will be removed later).
  *bits = buffer_[index] >> offset;

  const size_t num_read_from_first_word = std::min(64 - offset, num_bits);
  pos_ += num_read_from_first_word;

  if (pos_ >= buffer_.size() * 64) {
    // Reached end of buffer_.
    EmitSequence(*bits, num_read_from_first_word);
    return num_read_from_first_word;
  }

  if (offset + num_bits > 64) {
    // Requested |num_bits| overflows to next word.
    // Write all bits from the beginning of next word to *bits after offset.
    *bits |= buffer_[index + 1] << (64 - offset);
    pos_ += offset + num_bits - 64;
  }

  // We likely have written more bits than requested. Clear excessive bits.
  *bits = GetLowerBits(*bits, num_bits);
  EmitSequence(*bits, num_bits);
  return num_bits;
}

bool BitReaderWord64::ReachedEnd() const { return pos_ >= buffer_.size() * 64; }

bool BitReaderWord64::OnlyZeroesLeft() const {
  if (ReachedEnd()) return true;

  const size_t index = pos_ / 64;
  if (index < buffer_.size() - 1) return false;

  assert(index == buffer_.size() - 1);

  const size_t offset = pos_ % 64;
  const uint64_t remaining_bits = buffer_[index] >> offset;
  return !remaining_bits;
}

}  // namespace utils
}  // namespace spvtools
