/*
 * 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_v<StorageType>, "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_
