/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */

#ifndef ART_LIBARTBASE_BASE_BIT_STRING_H_
#define ART_LIBARTBASE_BASE_BIT_STRING_H_

#include "bit_struct.h"
#include "bit_utils.h"

#include <ostream>

namespace art {

struct BitStringChar;
inline std::ostream& operator<<(std::ostream& os, const BitStringChar& bc);

/**
 * A BitStringChar is a light-weight wrapper to read/write a single character
 * into a BitString, while restricting the bitlength.
 *
 * This is only intended for reading/writing into temporaries, as the representation is
 * inefficient for memory (it uses a word for the character and another word for the bitlength).
 *
 * See also BitString below.
 */
struct BitStringChar {
  using StorageType = uint32_t;
  static_assert(std::is_unsigned<StorageType>::value, "BitStringChar::StorageType must be unsigned");

  // BitStringChars are always zero-initialized by default. Equivalent to BitStringChar(0,0).
  BitStringChar() : data_(0u), bitlength_(0u) { }

  // Create a new BitStringChar whose data bits can be at most bitlength.
  BitStringChar(StorageType data, size_t bitlength)
      : data_(data), bitlength_(bitlength) {
    // All bits higher than bitlength must be set to 0.
    DCHECK_EQ(0u, data & ~MaskLeastSignificant(bitlength_))
        << "BitStringChar data out of range, data: " << data << ", bitlength: " << bitlength;
  }

  // What is the bitlength constraint for this character?
  // (Data could use less bits, but this is the maximum bit capacity at that BitString position).
  size_t GetBitLength() const {
    return bitlength_;
  }

  // Is there any capacity in this BitStringChar to store any data?
  bool IsEmpty() const {
    return bitlength_ == 0;
  }

  explicit operator StorageType() const {
    return data_;
  }

  bool operator==(StorageType storage) const {
    return data_ == storage;
  }

  bool operator!=(StorageType storage) const {
    return !(*this == storage);
  }

  // Compare equality against another BitStringChar. Note: bitlength is ignored.
  bool operator==(const BitStringChar& other) const {
    return data_ == other.data_;
  }

  // Compare non-equality against another BitStringChar. Note: bitlength is ignored.
  bool operator!=(const BitStringChar& other) const {
    return !(*this == other);
  }

  // Add a BitStringChar with an integer. The resulting BitStringChar's data must still fit within
  // this BitStringChar's bit length.
  BitStringChar operator+(StorageType storage) const {
    DCHECK_LE(storage, MaximumValue().data_ - data_) << "Addition would overflow " << *this;
    return BitStringChar(data_ + storage, bitlength_);
  }

  // Get the maximum representible value with the same bitlength.
  // (Useful to figure out the maximum value for this BitString position.)
  BitStringChar MaximumValue() const {
    StorageType maximimum_data = MaxInt<StorageType>(bitlength_);
    return BitStringChar(maximimum_data, bitlength_);
  }

 private:
  StorageType data_;  // Unused bits (outside of bitlength) are 0.
  size_t bitlength_;
  // Logically const. Physically non-const so operator= still works.
};

// Print e.g. "BitStringChar<10>(123)" where 10=bitlength, 123=data.
inline std::ostream& operator<<(std::ostream& os, const BitStringChar& bc) {
  os << "BitStringChar<" << bc.GetBitLength() << ">("
     << static_cast<BitStringChar::StorageType>(bc) << ")";
  return os;
}

/**
 *                           BitString
 *
 * MSB (most significant bit)                                LSB
 *  +------------+-----+------------+------------+------------+
 *  |            |     |            |            |            |
 *  |   CharN    | ... |    Char2   |   Char1    |   Char0    |
 *  |            |     |            |            |            |
 *  +------------+-----+------------+------------+------------+
 *   <- len[N] ->  ...  <- len[2] -> <- len[1] -> <- len[0] ->
 *
 * Stores up to "N+1" characters in a subset of a machine word. Each character has a different
 * bitlength, as defined by len[pos]. This BitString can be nested inside of a BitStruct
 * (see e.g. SubtypeCheckBitsAndStatus).
 *
 * Definitions:
 *
 *  "ABCDE...K"       := [A,B,C,D,E, ... K] + [0]*(N-idx(K)) s.t. N >= K.
 *                    // Padded with trailing 0s to fit (N+1) bitstring chars.
 *  MaxBitstringLen   := N+1
 *  StrLen(Bitstring) := I s.t. (I == 0 OR Char(I-1) != 0)
 *                              AND forall char in CharI..CharN : char == 0
 *                    // = Maximum length - the # of consecutive trailing zeroes.
 *  Bitstring[N]      := CharN
 *  Bitstring[I..N)   := [CharI, CharI+1, ... CharN-1]
 *
 * (These are used by the SubtypeCheckInfo definitions and invariants, see subtype_check_info.h)
 */
struct BitString {
  using StorageType = BitStringChar::StorageType;

  // As this is meant to be used only with "SubtypeCheckInfo",
  // the bitlengths and the maximum string length is tuned by maximizing the coverage of "Assigned"
  // bitstrings for instance-of and check-cast targets during Optimizing compilation.
  static constexpr size_t kBitSizeAtPosition[] = {12, 4, 11};         // len[] from header docs.
  static constexpr size_t kCapacity = arraysize(kBitSizeAtPosition);  // MaxBitstringLen above.

  // How many bits are needed to represent BitString[0..position)?
  static constexpr size_t GetBitLengthTotalAtPosition(size_t position) {
    size_t idx = 0;
    size_t sum = 0;
    while (idx < position && idx < kCapacity) {
      sum += kBitSizeAtPosition[idx];
      ++idx;
    }
    // TODO: precompute with CreateArray helper.

    return sum;
  }

  // What is the least-significant-bit for a position?
  // (e.g. to use with BitField{Insert,Extract,Clear}.)
  static constexpr size_t GetLsbForPosition(size_t position) {
    DCHECK_GE(kCapacity, position);
    return GetBitLengthTotalAtPosition(position);
  }

  // How many bits are needed for a BitStringChar at the position?
  // Returns 0 if the position is out of range.
  static constexpr size_t MaybeGetBitLengthAtPosition(size_t position) {
    if (position >= kCapacity) {
      return 0;
    }
    return kBitSizeAtPosition[position];
  }

  // Read a bitchar at some index within the capacity.
  // See also "BitString[N]" in the doc header.
  BitStringChar operator[](size_t idx) const {
    DCHECK_LT(idx, kCapacity);

    StorageType data = BitFieldExtract(storage_, GetLsbForPosition(idx), kBitSizeAtPosition[idx]);

    return BitStringChar(data, kBitSizeAtPosition[idx]);
  }

  // Overwrite a bitchar at a position with a new one.
  //
  // The `bitchar` bitlength must be no more than the maximum bitlength for that position.
  void SetAt(size_t idx, BitStringChar bitchar) {
    DCHECK_LT(idx, kCapacity);
    DCHECK_LE(bitchar.GetBitLength(), kBitSizeAtPosition[idx]);

    // Read the bitchar: Bits > bitlength in bitchar are defined to be 0.
    storage_ = BitFieldInsert(storage_,
                              static_cast<StorageType>(bitchar),
                              GetLsbForPosition(idx),
                              kBitSizeAtPosition[idx]);
  }

  // How many characters are there in this bitstring?
  // Trailing 0s are ignored, but 0s in-between are counted.
  // See also "StrLen(BitString)" in the doc header.
  size_t Length() const {
    size_t num_trailing_zeros = 0;
    size_t i;
    for (i = kCapacity - 1u; ; --i) {
      BitStringChar bc = (*this)[i];
      if (bc != 0u) {
        break;  // Found first trailing non-zero.
      }

      ++num_trailing_zeros;
      if (i == 0u) {
        break;  // No more bitchars remaining: don't underflow.
      }
    }

    return kCapacity - num_trailing_zeros;
  }

  // Cast to the underlying integral storage type.
  explicit operator StorageType() const {
    return storage_;
  }

  // Get the # of bits this would use if it was nested inside of a BitStruct.
  static constexpr size_t BitStructSizeOf() {
    return GetBitLengthTotalAtPosition(kCapacity);
  }

  BitString() = default;

  // Efficient O(1) comparison: Equal if both bitstring words are the same.
  bool operator==(const BitString& other) const {
    return storage_ == other.storage_;
  }

  // Efficient O(1) negative comparison: Not-equal if both bitstring words are different.
  bool operator!=(const BitString& other) const {
    return !(*this == other);
  }

  // Does this bitstring contain exactly 0 characters?
  bool IsEmpty() const {
    return (*this) == BitString{};
  }

  // Remove all BitStringChars starting at end.
  // Returns the BitString[0..end) substring as a copy.
  // See also "BitString[I..N)" in the doc header.
  BitString Truncate(size_t end) {
    DCHECK_GE(kCapacity, end);
    BitString copy = *this;

    if (end < kCapacity) {
      size_t lsb = GetLsbForPosition(end);
      size_t bit_size = GetLsbForPosition(kCapacity) - lsb;
      StorageType data = BitFieldClear(copy.storage_, lsb, bit_size);
      copy.storage_ = data;
    }

    return copy;
  }

 private:
  friend std::ostream& operator<<(std::ostream& os, const BitString& bit_string);

  // Data is stored with the first character in the least-significant-bit.
  // Unused bits are zero.
  StorageType storage_;
};

static_assert(BitSizeOf<BitString::StorageType>() >=
                  BitString::GetBitLengthTotalAtPosition(BitString::kCapacity),
              "Storage type is too small for the # of bits requested");

// Print e.g. "BitString[1,0,3]". Trailing 0s are dropped.
inline std::ostream& operator<<(std::ostream& os, const BitString& bit_string) {
  const size_t length = bit_string.Length();

  os << "BitString[";
  for (size_t i = 0; i < length; ++i) {
    BitStringChar bc = bit_string[i];
    if (i != 0) {
      os << ",";
    }
    os << static_cast<BitString::StorageType>(bc);
  }
  os << "]";
  return os;
}

}  // namespace art

#endif  // ART_LIBARTBASE_BASE_BIT_STRING_H_
