/*
 * 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_RUNTIME_SUBTYPE_CHECK_INFO_H_
#define ART_RUNTIME_SUBTYPE_CHECK_INFO_H_

#include "base/bit_string.h"
#include "base/logging.h"
#include "subtype_check_bits.h"

// Forward-declare for testing purposes.
struct SubtypeCheckInfoTest;

namespace art {

/**
 * SubtypeCheckInfo is a logical label for the class SubtypeCheck data, which is necessary to
 * perform efficient O(1) subtype comparison checks. See also subtype_check.h
 * for the more general explanation of how the labels are used overall.
 *
 * For convenience, we also store the class depth within an SubtypeCheckInfo, since nearly all
 * calculations are dependent on knowing the depth of the class.
 *
 * A SubtypeCheckInfo logically has:
 *          * Depth - How many levels up to the root (j.l.Object)?
 *          * PathToRoot - Possibly truncated BitString that encodes path to root
 *          * Next - The value a newly inserted Child would get appended to its path.
 *          * Overflow - If this path can never become a full path.
 *
 * Depending on the values of the above, it can be in one of these logical states,
 * which are introduced in subtype_check.h:
 *
 *               Transient States                         Terminal States
 *
 *  +-----------------+     +--------------------+     +-------------------+
 *  |                 |     |                    |     |                   |
 *  |  Uninitialized  | +--->    Initialized     | +--->     Assigned      |
 *  |                 |     |                    |     |                   |
 *  +--------+--------+     +---------+----------+     +-------------------+
 *           |                        |
 *           |                        |
 *           |                        |                +-------------------+
 *           |                        +---------------->                   |
 *           |                                         |     Overflowed    |
 *           +----------------------------------------->                   |
 *                                                     +-------------------+
 *
 * Invariants:
 *
 *   Initialized      => Parent >= Initialized
 *
 *   Assigned         => Parent == Assigned
 *
 *   Overflowed       => Parent == Overflowed || Parent.Next == Overflowed
 *
 * Thread-safety invariants:
 *
 *   Initialized      => Parent == Assigned
 *   // For a class that has an Initialized bitstring, its superclass needs to have an
 *   // Assigned bitstring since if its super class's bitstring is not Assigned yet,
 *   // once it becomes Assigned, we cannot update its children's bitstrings to maintain
 *   // all the tree invariants (below) atomically.
 *
 * --------------------------------------------------------------------------------------------
 * Knowing these transitions above, we can more closely define the various terms and operations:
 *
 * Definitions:
 *   (see also base/bit_string.h definitions).
 *
 *           Depth :=  Distance(Root, Class)
 *     Safe(Depth) :=  Min(Depth, MaxBitstringLen)
 *      PathToRoot :=  Bitstring[0..Safe(Depth))
 *           Next  :=  Bitstring[Depth]
 *           OF    ∈   {False, True}
 *    TruncPath(D) :=  PathToRoot[0..D)
 *
 * Local Invariants:
 *
 *   Uninitialized <=> StrLen(PathToRoot) == 0
 *                     Next == 0
 *                     OF == False
 *   Initialized   <=> StrLen(PathToRoot) < Depth
 *                     Next == 1
 *                     OF == False
 *   Assigned      <=> StrLen(PathToRoot) == Depth
 *                     Next >= 1
 *                     OF == False
 *   Overflowed    <=> OF == True
 *
 * Tree Invariants:
 *
 *   Uninitialized =>
 *     forall child ∈ Children(Class):
 *       child.State == Uninitialized
 *
 *   Assigned       =>
 *     forall child ∈ Children(Class):
 *       Next > Child.PathToRoot[Child.Depth-1]
 *
 *   ! Uninitialized =>
 *     forall ancestor ∈ Ancestors(Class):
 *       TruncPath(ancestor.Depth) == ancestor.PathToRoot
 *     forall unrelated ∈ (Classes - Ancestors(Class))
 *         s.t. unrelated.State == Assigned:
 *       TruncPath(unrelated.Depth) != unrelated.PathToRoot
 *
 * Thread-safety invariants:
 *
 *   Initialized   <=> StrLen(PathToRoot) == Safe(Depth - 1)
 *   // Initialized State corresponds to exactly 1 bitstring.
 *   // Cannot transition from Initialized to Initialized.
 */
struct SubtypeCheckInfo {
  // See above documentation for possible state transitions.
  enum State {
    kUninitialized,
    kInitialized,
    kAssigned,
    kOverflowed
  };

  // The result of a "src IsSubType target" check:
  enum Result {
    kUnknownSubtypeOf,  // Not enough data. Operand states weren't high enough.
    kNotSubtypeOf,      // Enough data. src is not a subchild of the target.
    kSubtypeOf          // Enough data. src is a subchild of the target.
  };

  // Get the raw depth.
  size_t GetDepth() const {
    return depth_;
  }

  // Chop off the depth, returning only the bitstring+of state.
  // (Used to store into memory, since storing the depth would be redundant.)
  SubtypeCheckBits GetSubtypeCheckBits() const {
    return bitstring_and_of_;
  }

  // Create from the depth and the bitstring+of state.
  // This is done for convenience to avoid passing in "depth" everywhere,
  // since our current state is almost always a function of depth.
  static SubtypeCheckInfo Create(SubtypeCheckBits compressed_value, size_t depth) {
    SubtypeCheckInfo io;
    io.depth_ = depth;
    io.bitstring_and_of_ = compressed_value;
    io.DcheckInvariants();
    return io;
  }

  // Is this a subtype of the target?
  //
  // The current state must be at least Initialized, and the target state
  // must be Assigned, otherwise the result will return kUnknownSubtypeOf.
  //
  // Normally, return kSubtypeOf or kNotSubtypeOf.
  Result IsSubtypeOf(const SubtypeCheckInfo& target) {
    if (target.GetState() != SubtypeCheckInfo::kAssigned) {
      return Result::kUnknownSubtypeOf;
    } else if (GetState() == SubtypeCheckInfo::kUninitialized) {
      return Result::kUnknownSubtypeOf;
    }

    BitString::StorageType source_value = GetEncodedPathToRoot();
    BitString::StorageType target_value = target.GetEncodedPathToRoot();
    BitString::StorageType target_mask = target.GetEncodedPathToRootMask();

    bool result = (source_value & target_mask) == (target_value);
    if (result) {
      DCHECK_EQ(GetPathToRoot().Truncate(target.GetSafeDepth()), target.GetPathToRoot())
          << "Source: " << *this << ", Target: " << target;
    } else {
      DCHECK_NE(GetPathToRoot().Truncate(target.GetSafeDepth()), target.GetPathToRoot())
          << "Source: " << *this << ", Target: " << target;
    }

    // Note: We could've also used shifts here, as described in subtype_check_bits.h,
    // but it doesn't make much of a difference in the Runtime since we aren't trying to optimize
    // for code size.

    return result ? Result::kSubtypeOf : Result::kNotSubtypeOf;
  }

  // Returns a new root SubtypeCheckInfo with a blank PathToRoot.
  // Post-condition: The return valued has an Assigned state.
  static SubtypeCheckInfo CreateRoot() {
    SubtypeCheckInfo io{};
    io.depth_ = 0u;
    io.SetNext(io.GetNext() + 1u);

    // The root is always considered assigned once it is no longer Initialized.
    DCHECK_EQ(SubtypeCheckInfo::kAssigned, io.GetState());
    return io;
  }

  // Copies the current PathToRoot into the child.
  //
  // If assign_next is true, then also assign a new SubtypeCheckInfo for a child by
  // assigning the current Next value to its PathToRoot[Depth] component.
  // Updates the current Next value as a side effect.
  //
  // Preconditions: State is either Assigned or Overflowed.
  // Returns: A new child >= Initialized state.
  SubtypeCheckInfo CreateChild(bool assign_next) {
    SubtypeCheckInfo child = *this;  // Copy everything (path, next, of).
    child.depth_ = depth_ + 1u;

    // Must be Assigned or Overflowed in order to create a subchild.
    DCHECK(GetState() == kAssigned || GetState() == kOverflowed)
        << "Unexpected bitstring state: " << GetState();

    // Begin transition to >= Initialized.

    // Always attempt to re-initialize Child's Next value.
    // Next must be non-0 to disambiguate it from Uninitialized.
    child.MaybeInitNext();

    // Always clear the inherited Parent's next Value, i.e. the child's last path entry.
    OverwriteNextValueFromParent(/*inout*/&child, BitStringChar{});

    // The state is now Initialized | Overflowed.
    DCHECK_NE(kAssigned, child.GetState()) << child.GetBitString();
    DCHECK_NE(kUninitialized, child.GetState()) << child.GetBitString();

    if (assign_next == false) {
      child.DcheckInvariants();
      return child;
    }

    // Begin transition to >= Assigned.

    // Assign attempt.
    if (HasNext() && !bitstring_and_of_.overflow_) {
      BitStringChar next = GetNext();
      if (next != next.MaximumValue()) {
        // The parent's "next" value is now the child's latest path element.
        OverwriteNextValueFromParent(/*inout*/&child, next);
        // Update self next value, so that future CreateChild calls
        // do not get the same path value.
        SetNext(next + 1u);
      } else {
        child.MarkOverflowed();  // Too wide.
      }
    } else {
      child.MarkOverflowed();  // Too deep, or parent was already overflowed.
    }

    // The state is now Assigned | Overflowed.
    DCHECK(child.GetState() == kAssigned || child.GetState() == kOverflowed);

    child.DcheckInvariants();
    return child;
  }

  // Get the current state (Uninitialized, Initialized, Assigned, or Overflowed).
  // See the "SubtypeCheckInfo" documentation above which explains how a state is determined.
  State GetState() const {
    if (bitstring_and_of_.overflow_) {
      // Overflowed if and only if the OF bit was set.
      return kOverflowed;
    }

    if (GetBitString().IsEmpty()) {
      // Empty bitstring (all 0s) -> uninitialized.
      return kUninitialized;
    }

    // Either Assigned or Initialized.
    BitString path_to_root = GetPathToRoot();

    DCHECK_IMPLIES(HasNext(), GetNext() != 0u)
        << "Expected (Assigned|Initialized) state to have >0 Next value: " << GetNext()
        << " path: " << path_to_root;

    if (path_to_root.Length() == depth_) {
      return kAssigned;
    }

    return kInitialized;
  }

  // Retrieve the path to root bitstring as a plain uintN_t value that is amenable to
  // be used by a fast check "encoded_src & mask_target == encoded_target".
  BitString::StorageType GetEncodedPathToRoot() const {
    BitString::StorageType data = static_cast<BitString::StorageType>(GetPathToRoot());
    // Bit strings are logically in the least-significant memory.
    return data;
  }

  // Retrieve the path to root bitstring mask as a plain uintN_t that is amenable to
  // be used by a fast check "encoded_src & mask_target == encoded_target".
  BitString::StorageType GetEncodedPathToRootMask() const {
    size_t num_bitchars = GetSafeDepth();
    size_t bitlength = BitString::GetBitLengthTotalAtPosition(num_bitchars);
    return MaskLeastSignificant<BitString::StorageType>(bitlength);
  }

  // Get the "Next" bitchar, assuming that there is one to get.
  BitStringChar GetNext() const {
    DCHECK(HasNext());
    return GetBitString()[depth_];
  }

  // Try to get the Next value, if there is one.
  // Returns: Whether or not there was a Next value.
  bool MaybeGetNext(/*out*/BitStringChar* next) const {
    DCHECK(next != nullptr);

    if (HasNext()) {
      *next = GetBitString()[depth_];
      return true;
    }
    return false;
  }

 private:
  // Constructor intended for testing. Runs all invariant checks.
  SubtypeCheckInfo(BitString path_to_root, BitStringChar next, bool overflow, size_t depth) {
    SubtypeCheckBits iod;
    iod.bitstring_ = path_to_root;
    iod.overflow_ = overflow;

    bitstring_and_of_ = iod;
    depth_ = depth;

    // Len(Path-to-root) <= Depth.
    DCHECK_GE(depth_, path_to_root.Length())
        << "Path was too long for the depth, path: " << path_to_root;

    bool did_overlap = false;
    if (HasNext()) {
      if (kIsDebugBuild) {
        did_overlap = (GetNext() != 0u);
      }

      SetNext(next);

      DCHECK_EQ(next, GetNext());
    }
    // "Next" must be set before we can check the invariants.
    DcheckInvariants();
    DCHECK(!did_overlap)
          << "Path to root overlapped with Next value, path: " << path_to_root;
    DCHECK_EQ(path_to_root, GetPathToRoot());
  }

  // Factory intended for testing. Skips DcheckInvariants.
  static SubtypeCheckInfo MakeUnchecked(BitString bitstring, bool overflow, size_t depth) {
    SubtypeCheckBits iod;
    iod.bitstring_ = bitstring;
    iod.overflow_ = overflow;

    SubtypeCheckInfo io;
    io.depth_ = depth;
    io.bitstring_and_of_ = iod;

    return io;
  }

  void SetNext(BitStringChar next) {
    DCHECK(HasNext());
    BitString bs = GetBitString();
    bs.SetAt(depth_, next);
    SetBitString(bs);
  }

  void SetNextUnchecked(BitStringChar next) {
    BitString bs = GetBitString();
    bs.SetAt(depth_, next);
    SetBitStringUnchecked(bs);
  }

  // If there is a next field, set it to 1.
  void MaybeInitNext() {
    if (HasNext()) {
      // Clearing out the "Next" value like this
      // is often an intermediate operation which temporarily
      // violates the invariants. Do not do the extra dchecks.
      SetNextUnchecked(BitStringChar{});
      SetNextUnchecked(GetNext()+1u);
    }
  }

  BitString GetPathToRoot() const {
    size_t end = GetSafeDepth();
    return GetBitString().Truncate(end);
  }

  bool HasNext() const {
    return depth_ < BitString::kCapacity;
  }

  void MarkOverflowed() {
    bitstring_and_of_.overflow_ = true;
  }

  static constexpr bool HasBitStringCharStorage(size_t idx) {
    return idx < BitString::kCapacity;
  }

  size_t GetSafeDepth() const {
    return GetSafeDepth(depth_);
  }

  // Get a "safe" depth, one that is truncated to the bitstring max capacity.
  // Using a value larger than this will cause undefined behavior.
  static size_t GetSafeDepth(size_t depth) {
    return std::min(depth, BitString::kCapacity);
  }

  BitString GetBitString() const {
    return bitstring_and_of_.bitstring_;
  }

  void SetBitString(const BitString& val) {
    SetBitStringUnchecked(val);
    DcheckInvariants();
  }

  void SetBitStringUnchecked(const BitString& val) {
    bitstring_and_of_.bitstring_ = val;
  }

  void OverwriteNextValueFromParent(/*inout*/SubtypeCheckInfo* child, BitStringChar value) const {
    // Helper function for CreateChild.
    if (HasNext()) {
      // When we copied the "Next" value, it is now our
      // last path component in the child.
      // Always overwrite it with either a cleared value or the parent's Next value.
      BitString bs = child->GetBitString();

      // Safe write. This.Next always occupies same slot as Child[Depth_].
      DCHECK(child->HasBitStringCharStorage(depth_));

      bs.SetAt(depth_, value);

      // The child is temporarily in a bad state until it is fixed up further.
      // Do not do the normal dchecks which do not allow transient badness.
      child->SetBitStringUnchecked(bs);
    }
  }

  void DcheckInvariants() const {
    if (kIsDebugBuild) {
      CHECK_GE(GetSafeDepth(depth_ + 1u), GetBitString().Length())
          << "Bitstring too long for depth, bitstring: " << GetBitString() << ", depth: " << depth_;

      BitString path_to_root = GetPathToRoot();

      // A 'null' (\0) character in path-to-root must be followed only
      // by other null characters.
      size_t i;
      for (i = 0; i < BitString::kCapacity; ++i) {
        BitStringChar bc = path_to_root[i];
        if (bc == 0u) {
          break;
        }
      }

      // All characters following a 0 must also be 0.
      for (; i < BitString::kCapacity; ++i) {
        BitStringChar bc = path_to_root[i];
        if (bc != 0u) {
          LOG(FATAL) << "Path to root had non-0s following 0s: " << path_to_root;
        }
      }

       // Trigger any dchecks in GetState.
      (void)GetState();
    }
  }

  SubtypeCheckInfo() = default;
  size_t depth_;
  SubtypeCheckBits bitstring_and_of_;

  friend struct ::SubtypeCheckInfoTest;
  friend std::ostream& operator<<(std::ostream& os, const SubtypeCheckInfo& io);
};

// Prints the SubtypeCheckInfo::State, e.g. "kUnitialized".
inline std::ostream& operator<<(std::ostream& os, const SubtypeCheckInfo::State& state) {
  switch (state) {
    case SubtypeCheckInfo::kUninitialized:
      os << "kUninitialized";
      break;
    case SubtypeCheckInfo::kInitialized:
      os << "kInitialized";
      break;
    case SubtypeCheckInfo::kAssigned:
      os << "kAssigned";
      break;
    case SubtypeCheckInfo::kOverflowed:
      os << "kOverflowed";
      break;
    default:
      os << "(Invalid SubtypeCheckInfo::State " << static_cast<int>(state) << ")";
  }
  return os;
}

// Prints e.g. "SubtypeCheckInfo{BitString[1,2,3], depth: 3, of:1}"
inline std::ostream& operator<<(std::ostream& os, const SubtypeCheckInfo& io) {
  os << "SubtypeCheckInfo{" << io.GetBitString() << ", "
     << "depth: " << io.depth_ << ", of:" << io.bitstring_and_of_.overflow_ << "}";
  return os;
}

}  // namespace art

#endif  // ART_RUNTIME_SUBTYPE_CHECK_INFO_H_
