// Copyright 2020 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 "lib/fidl/cpp/internal/bitset.h"

#include <gtest/gtest.h>

namespace fidl {
namespace internal {
namespace {

template <size_t Min, size_t Max>
struct RangeChecker {
  static_assert(Max >= Min);

  template <size_t N>
  static void AllTrue(const BitSet<N>& bitset) {
    EXPECT_TRUE(bitset.template IsSet<Max>());
    if constexpr (Min != Max) {
      RangeChecker<Min, Max - 1>::AllTrue(bitset);
    }
  }

  template <size_t N>
  static void AllFalse(const BitSet<N>& bitset) {
    EXPECT_FALSE(bitset.template IsSet<Max>());
    if constexpr (Min != Max) {
      RangeChecker<Min, Max - 1>::AllFalse(bitset);
    }
  }
};

TEST(BitSet, HasExpectedSize) {
  static_assert(sizeof(BitSet<0>) == 1);  // Empty struct specialization.
  static_assert(sizeof(BitSet<1>) == 8);
  static_assert(sizeof(BitSet<3>) == 8);
  static_assert(sizeof(BitSet<64>) == 8);
  static_assert(sizeof(BitSet<65>) == 16);
  static_assert(sizeof(BitSet<79>) == 16);
  static_assert(sizeof(BitSet<128>) == 16);
  static_assert(sizeof(BitSet<129>) == 24);
}

TEST(BitSet, ZeroBitSet) {
  BitSet<0> bitset;
  EXPECT_TRUE(bitset.IsEmpty());
  EXPECT_EQ(bitset.MaxSetIndex(), -1);

  BitSet<0> second = bitset;
  EXPECT_TRUE(second.IsEmpty());
  EXPECT_EQ(second.MaxSetIndex(), -1);
}

TEST(BitSet, EmptyBitSet) {
  BitSet<100> bitset;
  RangeChecker<0, 99>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsEmpty());
  EXPECT_EQ(bitset.MaxSetIndex(), -1);
}

TEST(BitSet, SetClearIsSet) {
  BitSet<200> bitset;
  RangeChecker<0, 199>::AllFalse(bitset);

  bitset.Set<0>();
  bitset.Set<20>();
  bitset.Set<160>();
  bitset.Set<199>();
  EXPECT_TRUE(bitset.IsSet<0>());
  RangeChecker<1, 19>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<20>());
  RangeChecker<21, 159>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<160>());
  RangeChecker<161, 198>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<199>());

  bitset.Clear<0>();
  bitset.Clear<160>();
  bitset.Clear<199>();
  RangeChecker<0, 19>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<20>());
  RangeChecker<21, 199>::AllFalse(bitset);
}

TEST(BitSet, IsEmpty) {
  BitSet<200> bitset;
  EXPECT_TRUE(bitset.IsEmpty());

  bitset.Set<199>();
  EXPECT_FALSE(bitset.IsEmpty());
  bitset.Clear<199>();
  EXPECT_TRUE(bitset.IsEmpty());

  bitset.Set<0>();
  EXPECT_FALSE(bitset.IsEmpty());
  bitset.Clear<0>();
  EXPECT_TRUE(bitset.IsEmpty());

  bitset.Set<121>();
  EXPECT_FALSE(bitset.IsEmpty());
  bitset.Clear<121>();
  EXPECT_TRUE(bitset.IsEmpty());
}

TEST(BitSet, MaxSetIndex) {
  BitSet<200> bitset;
  EXPECT_EQ(bitset.MaxSetIndex(), -1);

  bitset.Set<0>();
  EXPECT_EQ(bitset.MaxSetIndex(), 0);

  bitset.Set<3>();
  EXPECT_EQ(bitset.MaxSetIndex(), 3);

  bitset.Set<63>();
  EXPECT_EQ(bitset.MaxSetIndex(), 63);

  bitset.Set<64>();
  EXPECT_EQ(bitset.MaxSetIndex(), 64);

  bitset.Set<113>();
  EXPECT_EQ(bitset.MaxSetIndex(), 113);

  bitset.Set<199>();
  EXPECT_EQ(bitset.MaxSetIndex(), 199);

  bitset.Clear<199>();
  EXPECT_EQ(bitset.MaxSetIndex(), 113);
}

TEST(BitSet, CopyConstructor) {
  BitSet<200> bitset;
  bitset.Set<79>();

  RangeChecker<1, 78>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<79>());
  RangeChecker<80, 199>::AllFalse(bitset);

  BitSet<200> other = bitset;

  RangeChecker<1, 78>::AllFalse(other);
  EXPECT_TRUE(other.IsSet<79>());
  RangeChecker<80, 199>::AllFalse(other);

  // Setting a bit in one shouldn't effect the other.
  other.Set<21>();
  EXPECT_FALSE(bitset.IsSet<21>());
  bitset.Set<20>();
  EXPECT_FALSE(other.IsSet<20>());
}

TEST(BitSet, CopyAssignment) {
  BitSet<200> bitset;
  bitset.Set<79>();

  RangeChecker<1, 78>::AllFalse(bitset);
  EXPECT_TRUE(bitset.IsSet<79>());
  RangeChecker<80, 199>::AllFalse(bitset);

  BitSet<200> other;
  other = bitset;

  RangeChecker<1, 78>::AllFalse(other);
  EXPECT_TRUE(other.IsSet<79>());
  RangeChecker<80, 199>::AllFalse(other);

  // Setting a bit in one shouldn't effect the other.
  other.Set<21>();
  EXPECT_FALSE(bitset.IsSet<21>());
  bitset.Set<20>();
  EXPECT_FALSE(other.IsSet<20>());
}

}  // namespace
}  // namespace internal
}  // namespace fidl
