// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include <type_traits>
#include <unordered_set>

#include <fbl/strong_int.h>
#include <zxtest/zxtest.h>

namespace {

TEST(StrongIntTest, TwoUint64DontConvert) {
  DEFINE_STRONG_INT(CpuCount, uint64_t);
  DEFINE_STRONG_INT(MemoryBytes, uint64_t);
  static_assert(!std::is_same<CpuCount, MemoryBytes>::value);
}

TEST(StrongIntTest, TwoUintsOfDifferentSizeDontConvert) {
  DEFINE_STRONG_INT(CpuCount, uint32_t);
  DEFINE_STRONG_INT(MemoryBytes, uint64_t);
  static_assert(!std::is_same<CpuCount, MemoryBytes>::value);
}

TEST(StrongIntTest, SameTypesWork) {
  DEFINE_STRONG_INT(Kilometers, uint32_t);

  Kilometers near(1), nearer(1);
  Kilometers far(2);
  ASSERT_EQ(near, nearer);
  ASSERT_NE(near, far);
  ASSERT_NE(near.value(), far.value());
  static_assert(Kilometers(1) < Kilometers(2));
  ASSERT_LT(near, far);
  near = far;
  ASSERT_EQ(near, far);
  std::swap(near, far);
  ASSERT_EQ(near, far);
}

TEST(StrongIntTest, ArithmaticOperations) {
  DEFINE_STRONG_INT(Strong, uint32_t);

  // Binary operators.
  static_assert((Strong(1) + Strong(2)) == Strong(3));
  static_assert((Strong(3) - Strong(1)) == Strong(2));
  static_assert((Strong(6) & Strong(2)) == Strong(2));
  static_assert((Strong(1) | Strong(2)) == Strong(3));
  static_assert((Strong(1) ^ Strong(2)) == Strong(3));

  static_assert((Strong(6) / 3) == Strong(2));
  static_assert((Strong(6) / Strong(3)) == 2);

  static_assert((Strong(2) * 3) == Strong(6));
  static_assert(3 * (Strong(2)) == Strong(6));

  static_assert((Strong(3) % 2) == Strong(1));
  static_assert((Strong(3) % Strong(2)) == Strong(1));

  static_assert((Strong(1) << 2) == Strong(4));
  static_assert((Strong(4) >> 1) == Strong(2));

  // Unary operators.
  static_assert(~Strong(0) == Strong(0xffffffff));
  static_assert(+Strong(6) == Strong(6));
  static_assert(-Strong(6) == Strong(-6));

  // explicit operator bool()
  if (Strong(0)) {
    FAIL();
  }
  if (!Strong(1)) {
    FAIL();
  }
  if (!Strong(100)) {
    FAIL();
  }
  if (Strong(1) && Strong(0)) {
    FAIL();
  }
  if (!Strong(1) || Strong(0)) {
    FAIL();
  }

  // Increment / decrement.
  {
    Strong s{1};
    EXPECT_EQ(s++, Strong{1});
    EXPECT_EQ(s, Strong{2});
  }
  {
    Strong s{1};
    EXPECT_EQ(++s, Strong{2});
    EXPECT_EQ(s, Strong{2});
  }
  {
    Strong s{1};
    EXPECT_EQ(s--, Strong{1});
    EXPECT_EQ(s, Strong{0});
  }
  {
    Strong s{1};
    EXPECT_EQ(--s, Strong{0});
    EXPECT_EQ(s, Strong{0});
  }

  // Update operators.
  // clang-format off
  { Strong s{1}; s  += Strong{2}; EXPECT_EQ(s, Strong(3)); }
  { Strong s{2}; s  -= Strong{1}; EXPECT_EQ(s, Strong(1)); }
  { Strong s{2}; s  &= Strong{3}; EXPECT_EQ(s, Strong(2)); }
  { Strong s{2}; s  |= Strong{1}; EXPECT_EQ(s, Strong(3)); }
  { Strong s{2}; s  ^= Strong{3}; EXPECT_EQ(s, Strong(1)); }
  { Strong s{6}; s  /= 2; EXPECT_EQ(s, Strong(3)); }
  { Strong s{2}; s  *= 3; EXPECT_EQ(s, Strong(6)); }
  { Strong s{6}; s  %= Strong{5}; EXPECT_EQ(s, Strong(1)); }
  { Strong s{4}; s >>= 1; EXPECT_EQ(s, Strong(2)); }
  { Strong s{1}; s <<= 1; EXPECT_EQ(s, Strong(2)); }
  // clang-format on

  // Update operators with plain RHS.
  // clang-format off
  { Strong s{6}; s  /= 2; EXPECT_EQ(s, Strong(3)); }
  { Strong s{2}; s  *= 3; EXPECT_EQ(s, Strong(6)); }
  { Strong s{6}; s  %= 5; EXPECT_EQ(s, Strong(1)); }
  { Strong s{4}; s >>= 1; EXPECT_EQ(s, Strong(2)); }
  { Strong s{1}; s <<= 1; EXPECT_EQ(s, Strong(2)); }
  // clang-format on
}

TEST(StrongIntTest, ChainedOps) {
  DEFINE_STRONG_INT(Strong, uint32_t);

  // Multiple arithmetic operations.
  {
    Strong x = (-Strong(1) + Strong(10) - Strong(1)) & (Strong(0xf) | Strong(0));
    EXPECT_EQ(x, Strong(8));
  }

  // Multiple in-place arithmetic operators.
  {
    Strong x = Strong(1);
    Strong y = Strong(1);
    Strong z = Strong(1);
    x += (y += (z += Strong(1)));
    EXPECT_EQ(z, Strong(2));
    EXPECT_EQ(y, Strong(3));
    EXPECT_EQ(x, Strong(4));
  }

  // Chained multiply / divide operators.
  {
    Strong a = Strong(1);

    EXPECT_EQ(a * 3 * 2 / 3 / Strong(2), 1);
  }

  // Multiple assignment operators.
  {
    Strong x = Strong(1);
    Strong y = Strong(2);
    Strong z = Strong(3);
    x = y = z;
    EXPECT_EQ(x, Strong(3));
    EXPECT_EQ(y, Strong(3));
  }

  // Multiple increment operators.
  {
    Strong a = Strong(1);
    Strong b = Strong(2);
    Strong c = (a++) + (++b);
    EXPECT_EQ(a, Strong(2));
    EXPECT_EQ(b, Strong(3));
    EXPECT_EQ(c, Strong(4));
  }
}

TEST(StrongIntTest, Hashing) {
  DEFINE_STRONG_INT(Strong, uint64_t);

  // std::hash delegates to the underlying type.
  {
    EXPECT_EQ(std::hash<uint64_t>()(0), std::hash<Strong>()(Strong(0)));
    EXPECT_EQ(std::hash<uint64_t>()(1), std::hash<Strong>()(Strong(1)));
    EXPECT_EQ(std::hash<uint64_t>()(42), std::hash<Strong>()(Strong(42)));
  }

  // Correct integration with a type that uses std::hash.
  {
    std::unordered_set<Strong> hashed_set;
    hashed_set.insert(Strong(1));
    hashed_set.insert(Strong(3));
    hashed_set.insert(Strong(5));

    EXPECT_EQ(1u, hashed_set.count(Strong(1)));
    EXPECT_EQ(0u, hashed_set.count(Strong(2)));
    EXPECT_EQ(1u, hashed_set.count(Strong(3)));
  }
}

}  // anonymous namespace
