/*
 * 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.
 */

#include "subtype_check_info.h"

#include "gtest/gtest.h"
#include "android-base/logging.h"

namespace art {

constexpr size_t BitString::kBitSizeAtPosition[BitString::kCapacity];
constexpr size_t BitString::kCapacity;

};  // namespace art

using namespace art;  // NOLINT

// These helper functions are only used by the test,
// so they are not in the main BitString class.
std::string Stringify(BitString bit_string) {
  std::stringstream ss;
  ss << bit_string;
  return ss.str();
}

BitStringChar MakeBitStringChar(size_t idx, size_t val) {
  return BitStringChar(val, BitString::MaybeGetBitLengthAtPosition(idx));
}

BitStringChar MakeBitStringChar(size_t val) {
  return BitStringChar(val, MinimumBitsToStore(val));
}

BitString MakeBitString(std::initializer_list<size_t> values = {}) {
  CHECK_GE(BitString::kCapacity, values.size());

  BitString bs{};

  size_t i = 0;
  for (size_t val : values) {
    bs.SetAt(i, MakeBitStringChar(i, val));
    ++i;
  }

  return bs;
}

template <typename T>
size_t AsUint(const T& value) {
  size_t uint_value = 0;
  memcpy(&uint_value, &value, sizeof(value));
  return uint_value;
}

// Make max bistring, e.g. BitString[4095,15,2047] for {12,4,11}
template <size_t kCount = BitString::kCapacity>
BitString MakeBitStringMax() {
  BitString bs{};

  for (size_t i = 0; i < kCount; ++i) {
    bs.SetAt(i,
             MakeBitStringChar(i, MaxInt<BitStringChar::StorageType>(BitString::kBitSizeAtPosition[i])));
  }

  return bs;
}

BitString SetBitStringCharAt(BitString bit_string, size_t i, size_t val) {
  BitString bs = bit_string;
  bs.SetAt(i, MakeBitStringChar(i, val));
  return bs;
}

struct SubtypeCheckInfoTest : public ::testing::Test {
 protected:
  void SetUp() override {
    android::base::InitLogging(/*argv=*/nullptr);
  }

  void TearDown() override {
  }

  static SubtypeCheckInfo MakeSubtypeCheckInfo(BitString path_to_root = {},
                                               BitStringChar next = {},
                                               bool overflow = false,
                                               size_t depth = 1u) {
    // Depth=1 is good default because it will go through all state transitions,
    // and its children will also go through all state transitions.
    return SubtypeCheckInfo(path_to_root, next, overflow, depth);
  }

  static SubtypeCheckInfo MakeSubtypeCheckInfoInfused(BitString bs = {},
                                                      bool overflow = false,
                                                      size_t depth = 1u) {
    // Depth=1 is good default because it will go through all state transitions,
    // and its children will also go through all state transitions.
    SubtypeCheckBits iod;
    iod.bitstring_ = bs;
    iod.overflow_ = overflow;
    return SubtypeCheckInfo::Create(iod, depth);
  }

  static SubtypeCheckInfo MakeSubtypeCheckInfoUnchecked(BitString bs = {},
                                                        bool overflow = false,
                                                        size_t depth = 1u) {
    // Depth=1 is good default because it will go through all state transitions,
    // and its children will also go through all state transitions.
    return SubtypeCheckInfo::MakeUnchecked(bs, overflow, depth);
  }

  static bool HasNext(const SubtypeCheckInfo& io) {
    return io.HasNext();
  }

  static BitString GetPathToRoot(const SubtypeCheckInfo& io) {
    return io.GetPathToRoot();
  }

  // Create an SubtypeCheckInfo with the same depth, but with everything else reset.
  // Returns: SubtypeCheckInfo in the Uninitialized state.
  static SubtypeCheckInfo CopyCleared(const SubtypeCheckInfo& sc) {
    SubtypeCheckInfo cleared_copy{};
    cleared_copy.depth_ = sc.depth_;
    DCHECK_EQ(SubtypeCheckInfo::kUninitialized, cleared_copy.GetState());
    return cleared_copy;
  }
};

const char* GetExpectedMessageForDeathTest(const char* msg) {
#ifdef ART_TARGET_ANDROID
  // On Android, dcheck failure messages go to logcat,
  // which gtest death tests does not check, and thus the tests would fail with
  // "unexpected message ''"
  UNUSED(msg);
  return "";  // Still ensures there was a bad return code, but match anything.
#else
  return msg;
#endif
}

TEST_F(SubtypeCheckInfoTest, IllegalValues) {
  // This test relies on BitString being at least 3 large.
  // It will need to be updated otherwise.
  ASSERT_LE(3u, BitString::kCapacity);

  // Illegal values during construction would cause a Dcheck failure and crash.
  ASSERT_DEATH(MakeSubtypeCheckInfo(MakeBitString({1u}),
                                    /*next=*/MakeBitStringChar(0),
                                    /*overflow=*/false,
                                    /*depth=*/0u),
               GetExpectedMessageForDeathTest("Path was too long for the depth"));
  ASSERT_DEATH(MakeSubtypeCheckInfoInfused(MakeBitString({1u, 1u}),
                                           /*overflow=*/false,
                                           /*depth=*/0u),
               GetExpectedMessageForDeathTest("Bitstring too long for depth"));
  ASSERT_DEATH(MakeSubtypeCheckInfo(MakeBitString({1u}),
                                    /*next=*/MakeBitStringChar(0),
                                    /*overflow=*/false,
                                    /*depth=*/1u),
               GetExpectedMessageForDeathTest("Expected \\(Assigned\\|Initialized\\) "
                                              "state to have >0 Next value"));
  ASSERT_DEATH(MakeSubtypeCheckInfoInfused(MakeBitString({0u, 2u, 1u}),
                                           /*overflow=*/false,
                                           /*depth=*/2u),
               GetExpectedMessageForDeathTest("Path to root had non-0s following 0s"));
  ASSERT_DEATH(MakeSubtypeCheckInfo(MakeBitString({0u, 2u}),
                                    /*next=*/MakeBitStringChar(1u),
                                    /*overflow=*/false,
                                    /*depth=*/2u),
               GetExpectedMessageForDeathTest("Path to root had non-0s following 0s"));
  ASSERT_DEATH(MakeSubtypeCheckInfo(MakeBitString({0u, 1u, 1u}),
                                    /*next=*/MakeBitStringChar(0),
                                    /*overflow=*/false,
                                    /*depth=*/3u),
               GetExpectedMessageForDeathTest("Path to root had non-0s following 0s"));

  // These are really slow (~1sec per death test on host),
  // keep them down to a minimum.
}

TEST_F(SubtypeCheckInfoTest, States) {
  EXPECT_EQ(SubtypeCheckInfo::kUninitialized, MakeSubtypeCheckInfo().GetState());
  EXPECT_EQ(SubtypeCheckInfo::kInitialized,
            MakeSubtypeCheckInfo(/*path_to_root=*/{}, /*next=*/MakeBitStringChar(1)).GetState());
  EXPECT_EQ(SubtypeCheckInfo::kOverflowed,
            MakeSubtypeCheckInfo(/*path_to_root=*/{},
                                 /*next=*/MakeBitStringChar(1),
                                 /*overflow=*/true,
                                 /*depth=*/1u).GetState());
  EXPECT_EQ(SubtypeCheckInfo::kAssigned,
            MakeSubtypeCheckInfo(/*path_to_root=*/MakeBitString({1u}),
                                 /*next=*/MakeBitStringChar(1),
                                 /*overflow=*/false,
                                 /*depth=*/1u).GetState());

  // Test edge conditions: depth == BitString::kCapacity (No Next value).
  EXPECT_EQ(SubtypeCheckInfo::kAssigned,
            MakeSubtypeCheckInfo(/*path_to_root=*/MakeBitStringMax(),
                                 /*next=*/MakeBitStringChar(0),
                                 /*overflow=*/false,
                                 /*depth=*/BitString::kCapacity).GetState());
  EXPECT_EQ(SubtypeCheckInfo::kInitialized,
            MakeSubtypeCheckInfo(/*path_to_root=*/MakeBitStringMax<BitString::kCapacity - 1u>(),
                                 /*next=*/MakeBitStringChar(0),
                                 /*overflow=*/false,
                                 /*depth=*/BitString::kCapacity).GetState());
  // Test edge conditions: depth > BitString::kCapacity (Must overflow).
  EXPECT_EQ(SubtypeCheckInfo::kOverflowed,
            MakeSubtypeCheckInfo(/*path_to_root=*/MakeBitStringMax(),
                                 /*next=*/MakeBitStringChar(0),
                                 /*overflow=*/true,
                                 /*depth=*/BitString::kCapacity + 1u).GetState());
}

TEST_F(SubtypeCheckInfoTest, NextValue) {
  // Validate "Next" is correctly aliased as the Bitstring[Depth] character.
  EXPECT_EQ(MakeBitStringChar(1u), MakeSubtypeCheckInfoUnchecked(MakeBitString({1u, 2u, 3u}),
                                                                 /*overflow=*/false,
                                                                 /*depth=*/0u).GetNext());
  EXPECT_EQ(MakeBitStringChar(2u), MakeSubtypeCheckInfoUnchecked(MakeBitString({1u, 2u, 3u}),
                                                                 /*overflow=*/false,
                                                                 /*depth=*/1u).GetNext());
  EXPECT_EQ(MakeBitStringChar(3u), MakeSubtypeCheckInfoUnchecked(MakeBitString({1u, 2u, 3u}),
                                                                 /*overflow=*/false,
                                                                 /*depth=*/2u).GetNext());
  EXPECT_EQ(MakeBitStringChar(1u), MakeSubtypeCheckInfoUnchecked(MakeBitString({0u, 2u, 1u}),
                                                                 /*overflow=*/false,
                                                                 /*depth=*/2u).GetNext());
  // Test edge conditions: depth == BitString::kCapacity (No Next value).
  EXPECT_FALSE(HasNext(MakeSubtypeCheckInfoUnchecked(MakeBitStringMax<BitString::kCapacity>(),
                                                     /*overflow=*/false,
                                                     /*depth=*/BitString::kCapacity)));
  // Anything with depth >= BitString::kCapacity has no next value.
  EXPECT_FALSE(HasNext(MakeSubtypeCheckInfoUnchecked(MakeBitStringMax<BitString::kCapacity>(),
                                                     /*overflow=*/false,
                                                     /*depth=*/BitString::kCapacity + 1u)));
  EXPECT_FALSE(HasNext(MakeSubtypeCheckInfoUnchecked(MakeBitStringMax(),
                                                     /*overflow=*/false,
                                                     /*depth=*/std::numeric_limits<size_t>::max())));
}

template <size_t kPos = BitString::kCapacity>
size_t LenForPos() { return BitString::GetBitLengthTotalAtPosition(kPos); }

TEST_F(SubtypeCheckInfoTest, EncodedPathToRoot) {
  using StorageType = BitString::StorageType;

  SubtypeCheckInfo sci =
      MakeSubtypeCheckInfo(/*path_to_root=*/MakeBitStringMax(),
                           /*next=*/BitStringChar{},
                           /*overflow=*/false,
                           /*depth=*/BitString::kCapacity);
  // 0b000...111 where LSB == 1, and trailing 1s = the maximum bitstring representation.
  EXPECT_EQ(MaxInt<StorageType>(LenForPos()), sci.GetEncodedPathToRoot());

  // The rest of this test is written assuming kCapacity == 3 for convenience.
  // Please update the test if this changes.
  ASSERT_EQ(3u, BitString::kCapacity);
  ASSERT_EQ(12u, BitString::kBitSizeAtPosition[0]);
  ASSERT_EQ(4u, BitString::kBitSizeAtPosition[1]);
  ASSERT_EQ(11u, BitString::kBitSizeAtPosition[2]);

  SubtypeCheckInfo sci2 =
      MakeSubtypeCheckInfoUnchecked(MakeBitStringMax<2u>(),
                                   /*overflow=*/false,
                                   /*depth=*/BitString::kCapacity);

#define MAKE_ENCODED_PATH(pos0, pos1, pos2) \
    (((pos0) << 0) | \
     ((pos1) << BitString::kBitSizeAtPosition[0]) | \
     ((pos2) << (BitString::kBitSizeAtPosition[0] + BitString::kBitSizeAtPosition[1])))

  EXPECT_EQ(MAKE_ENCODED_PATH(MaxInt<BitString::StorageType>(12), 0b1111, 0b0),
            sci2.GetEncodedPathToRoot());
  EXPECT_EQ(MAKE_ENCODED_PATH(MaxInt<BitString::StorageType>(12), 0b1111, 0b11111111111),
            sci2.GetEncodedPathToRootMask());

  SubtypeCheckInfo sci3 =
      MakeSubtypeCheckInfoUnchecked(MakeBitStringMax<2u>(),
                                   /*overflow=*/false,
                                   /*depth=*/BitString::kCapacity - 1u);

  EXPECT_EQ(MAKE_ENCODED_PATH(MaxInt<BitString::StorageType>(12), 0b1111, 0b0),
            sci3.GetEncodedPathToRoot());
  EXPECT_EQ(MAKE_ENCODED_PATH(MaxInt<BitString::StorageType>(12), 0b1111, 0b0),
            sci3.GetEncodedPathToRootMask());

  SubtypeCheckInfo sci4 =
      MakeSubtypeCheckInfoUnchecked(MakeBitString({0b1010101u}),
                                   /*overflow=*/false,
                                   /*depth=*/BitString::kCapacity - 2u);

  EXPECT_EQ(MAKE_ENCODED_PATH(0b1010101u, 0b0000, 0b0), sci4.GetEncodedPathToRoot());
  EXPECT_EQ(MAKE_ENCODED_PATH(MaxInt<BitString::StorageType>(12), 0b0000, 0b0),
            sci4.GetEncodedPathToRootMask());
}

TEST_F(SubtypeCheckInfoTest, NewForRoot) {
  SubtypeCheckInfo sci = SubtypeCheckInfo::CreateRoot();
  EXPECT_EQ(SubtypeCheckInfo::kAssigned, sci.GetState());  // Root is always assigned.
  EXPECT_EQ(0u, GetPathToRoot(sci).Length());  // Root's path length is 0.
  EXPECT_TRUE(HasNext(sci));  // Root always has a "Next".
  EXPECT_EQ(MakeBitStringChar(1u), sci.GetNext());  // Next>=1 to disambiguate from Uninitialized.
}

TEST_F(SubtypeCheckInfoTest, CopyCleared) {
  SubtypeCheckInfo root = SubtypeCheckInfo::CreateRoot();
  EXPECT_EQ(MakeBitStringChar(1u), root.GetNext());

  SubtypeCheckInfo childC = root.CreateChild(/*assign_next=*/true);
  EXPECT_EQ(SubtypeCheckInfo::kAssigned, childC.GetState());
  EXPECT_EQ(MakeBitStringChar(2u), root.GetNext());  // Next incremented for Assign.
  EXPECT_EQ(MakeBitString({1u}), GetPathToRoot(childC));

  SubtypeCheckInfo cleared_copy = CopyCleared(childC);
  EXPECT_EQ(SubtypeCheckInfo::kUninitialized, cleared_copy.GetState());
  EXPECT_EQ(MakeBitString({}), GetPathToRoot(cleared_copy));

  // CopyCleared is just a thin wrapper around value-init and providing the depth.
  SubtypeCheckInfo cleared_copy_value =
      SubtypeCheckInfo::Create(SubtypeCheckBits{}, /*depth=*/1u);
  EXPECT_EQ(SubtypeCheckInfo::kUninitialized, cleared_copy_value.GetState());
  EXPECT_EQ(MakeBitString({}), GetPathToRoot(cleared_copy_value));
}

TEST_F(SubtypeCheckInfoTest, NewForChild2) {
  SubtypeCheckInfo root = SubtypeCheckInfo::CreateRoot();
  EXPECT_EQ(MakeBitStringChar(1u), root.GetNext());

  SubtypeCheckInfo childC = root.CreateChild(/*assign_next=*/true);
  EXPECT_EQ(SubtypeCheckInfo::kAssigned, childC.GetState());
  EXPECT_EQ(MakeBitStringChar(2u), root.GetNext());  // Next incremented for Assign.
  EXPECT_EQ(MakeBitString({1u}), GetPathToRoot(childC));
}

TEST_F(SubtypeCheckInfoTest, NewForChild) {
  SubtypeCheckInfo root = SubtypeCheckInfo::CreateRoot();
  EXPECT_EQ(MakeBitStringChar(1u), root.GetNext());

  SubtypeCheckInfo childA = root.CreateChild(/*assign_next=*/false);
  EXPECT_EQ(SubtypeCheckInfo::kInitialized, childA.GetState());
  EXPECT_EQ(MakeBitStringChar(1u), root.GetNext());  // Next unchanged for Initialize.
  EXPECT_EQ(MakeBitString({}), GetPathToRoot(childA));

  SubtypeCheckInfo childB = root.CreateChild(/*assign_next=*/false);
  EXPECT_EQ(SubtypeCheckInfo::kInitialized, childB.GetState());
  EXPECT_EQ(MakeBitStringChar(1u), root.GetNext());  // Next unchanged for Initialize.
  EXPECT_EQ(MakeBitString({}), GetPathToRoot(childB));

  SubtypeCheckInfo childC = root.CreateChild(/*assign_next=*/true);
  EXPECT_EQ(SubtypeCheckInfo::kAssigned, childC.GetState());
  EXPECT_EQ(MakeBitStringChar(2u), root.GetNext());  // Next incremented for Assign.
  EXPECT_EQ(MakeBitString({1u}), GetPathToRoot(childC));

  {
    size_t cur_depth = 1u;
    SubtypeCheckInfo latest_child = childC;
    while (cur_depth != BitString::kCapacity) {
      latest_child = latest_child.CreateChild(/*assign_next=*/true);
      ASSERT_EQ(SubtypeCheckInfo::kAssigned, latest_child.GetState());
      ASSERT_EQ(cur_depth + 1u, GetPathToRoot(latest_child).Length());
      cur_depth++;
    }

    // Future assignments will result in a too-deep overflow.
    SubtypeCheckInfo child_of_deep = latest_child.CreateChild(/*assign_next=*/true);
    EXPECT_EQ(SubtypeCheckInfo::kOverflowed, child_of_deep.GetState());
    EXPECT_EQ(GetPathToRoot(latest_child), GetPathToRoot(child_of_deep));

    // Assignment of too-deep overflow also causes overflow.
    SubtypeCheckInfo child_of_deep_2 = child_of_deep.CreateChild(/*assign_next=*/true);
    EXPECT_EQ(SubtypeCheckInfo::kOverflowed, child_of_deep_2.GetState());
    EXPECT_EQ(GetPathToRoot(child_of_deep), GetPathToRoot(child_of_deep_2));
  }

  {
    size_t cur_next = 2u;
    while (true) {
      if (cur_next == MaxInt<BitString::StorageType>(BitString::kBitSizeAtPosition[0u])) {
        break;
      }

      SubtypeCheckInfo child = root.CreateChild(/*assign_next=*/true);
      ASSERT_EQ(SubtypeCheckInfo::kAssigned, child.GetState());
      ASSERT_EQ(MakeBitStringChar(cur_next+1u), root.GetNext());
      ASSERT_EQ(MakeBitString({cur_next}), GetPathToRoot(child));

      cur_next++;
    }
    // Now the root will be in a state that further assigns will be too-wide overflow.

    // Initialization still succeeds.
    SubtypeCheckInfo child = root.CreateChild(/*assign_next=*/false);
    EXPECT_EQ(SubtypeCheckInfo::kInitialized, child.GetState());
    EXPECT_EQ(MakeBitStringChar(cur_next), root.GetNext());
    EXPECT_EQ(MakeBitString({}), GetPathToRoot(child));

    // Assignment goes to too-wide Overflow.
    SubtypeCheckInfo child_of = root.CreateChild(/*assign_next=*/true);
    EXPECT_EQ(SubtypeCheckInfo::kOverflowed, child_of.GetState());
    EXPECT_EQ(MakeBitStringChar(cur_next), root.GetNext());
    EXPECT_EQ(MakeBitString({}), GetPathToRoot(child_of));

    // Assignment of overflowed child still succeeds.
    // The path to root is the same.
    SubtypeCheckInfo child_of2 = child_of.CreateChild(/*assign_next=*/true);
    EXPECT_EQ(SubtypeCheckInfo::kOverflowed, child_of2.GetState());
    EXPECT_EQ(GetPathToRoot(child_of), GetPathToRoot(child_of2));
  }
}
