// Copyright 2023 The Pigweed Authors
//
// 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
//
//     https://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 <cctype>

#include "gtest/gtest.h"
#include "pw_fuzzer/fuzztest.h"
#include "pw_result/result.h"

// Most of the tests in this file only validate that the domains provided by
// Pigweed build, both with and without FuzzTest. Each domain comprises one or
// more FuzzTest domains, so the validation of the distribution of values
// produced by domains is left to and assumed from FuzzTest's own domain tests.

namespace pw::fuzzer {
namespace {

////////////////////////////////////////////////////////////////
// Constants, macros, and types used by the domain tests below.

constexpr size_t kSize = 8;
constexpr char kMin = 4;
constexpr char kMax = 16;

/// Generates a target function and fuzz test for a specific type.
///
/// The generated test simply checks that the provided domain can produce values
/// of the appropriate type. Generally, explicitly providing a target function
/// is preferred for readability, but this macro can be useful for templated
/// domains that are tested for many repetitive numerical types.
///
/// This macro should not be used directly. Instead, use
/// `FUZZ_TEST_FOR_INTEGRAL`, `FUZZ_TEST_FOR_FLOATING_POINT`, or
/// `FUZZ_TEST_FOR_ARITHMETIC`.
#define FUZZ_TEST_FOR_TYPE(Suite, Target, Domain, Type, ...) \
  void Target(Type t) { Take##Domain<Type>(t); }             \
  FUZZ_TEST(Suite, Target).WithDomains(Domain<Type>(__VA_ARGS__))

/// Generates target functions and fuzz tests for a integral types.
#define FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, ...)                     \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Char, Domain, char, __VA_ARGS__);         \
  FUZZ_TEST_FOR_TYPE(                                                          \
      Suite, Target##_UChar, Domain, unsigned char, __VA_ARGS__);              \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Short, Domain, short, __VA_ARGS__);       \
  FUZZ_TEST_FOR_TYPE(                                                          \
      Suite, Target##_UShort, Domain, unsigned short, __VA_ARGS__);            \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Int, Domain, int, __VA_ARGS__);           \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_UInt, Domain, unsigned int, __VA_ARGS__); \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Long, Domain, long, __VA_ARGS__);         \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_ULong, Domain, unsigned long, __VA_ARGS__)

/// Generates target functions and fuzz tests for a floating point types.
#define FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, ...)         \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Float, Domain, float, __VA_ARGS__); \
  FUZZ_TEST_FOR_TYPE(Suite, Target##_Double, Domain, double, __VA_ARGS__)

/// Generates target functions and fuzz tests for a all arithmetic types.
#define FUZZ_TEST_FOR_ARITHMETIC(Suite, Target, Domain, ...)  \
  FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, __VA_ARGS__); \
  FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, __VA_ARGS__)

// Test struct that can be produced by FuzzTest.
struct StructForTesting {
  int a;
  long b;
};

// Test class that can be produced by FuzzTest.
class ClassForTesting {
 public:
  ClassForTesting(unsigned char c, short d) : c_(c), d_(d) {}
  unsigned char c() const { return c_; }
  short d() const { return d_; }

 private:
  unsigned char c_;
  short d_;
};

////////////////////////////////////////////////////////////////
// Arbitrary domains forwarded or stubbed from FuzzTest

template <typename T>
void TakeArbitrary(T) {}

void TakeArbitraryBool(bool b) { TakeArbitrary<bool>(b); }
FUZZ_TEST(ArbitraryTest, TakeArbitraryBool).WithDomains(Arbitrary<bool>());

FUZZ_TEST_FOR_ARITHMETIC(ArbitraryTest, TakeArbitrary, Arbitrary);

void TakeArbitraryStruct(const StructForTesting& s) {
  TakeArbitrary<StructForTesting>(s);
}
FUZZ_TEST(ArbitraryTest, TakeArbitraryStruct)
    .WithDomains(Arbitrary<StructForTesting>());

void TakeArbitraryTuple(const std::tuple<int, long>& t) {
  TakeArbitrary<std::tuple<int, long>>(t);
}
FUZZ_TEST(ArbitraryTest, TakeArbitraryTuple)
    .WithDomains(Arbitrary<std::tuple<int, long>>());

void TakeArbitraryOptional(const std::optional<int>& o) {
  TakeArbitrary<std::optional<int>>(o);
}
FUZZ_TEST(ArbitraryTest, TakeArbitraryOptional)
    .WithDomains(Arbitrary<std::optional<int>>());

////////////////////////////////////////////////////////////////
// Numerical domains forwarded or stubbed from FuzzTest

template <typename Arithmetic>
void TakeInRange(Arithmetic x) {
  EXPECT_GE(x, Arithmetic(kMin));
  EXPECT_LE(x, Arithmetic(kMax));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeInRange, InRange, kMin, kMax);

template <typename Arithmetic>
void TakeNonZero(Arithmetic x) {
  EXPECT_NE(x, Arithmetic(0));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonZero, NonZero);

template <typename Arithmetic>
void TakePositive(Arithmetic x) {
  EXPECT_GT(x, Arithmetic(0));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakePositive, Positive);

template <typename Arithmetic>
void TakeNonNegative(Arithmetic x) {
  EXPECT_GE(x, Arithmetic(0));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonNegative, NonNegative);

template <typename Arithmetic>
void TakeNegative(Arithmetic x) {
  EXPECT_LT(x, Arithmetic(0));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNegative, Positive);

template <typename Arithmetic>
void TakeNonPositive(Arithmetic x) {
  EXPECT_LE(x, Arithmetic(0));
}
FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonPositive, NonNegative);

template <typename FloatingPoint>
void TakeFinite(FloatingPoint f) {
  EXPECT_TRUE(std::isfinite(f));
}
FUZZ_TEST_FOR_FLOATING_POINT(DomainTest, TakeFinite, Finite);

////////////////////////////////////////////////////////////////
// Character domains forwarded or stubbed from FuzzTest

void TakeNonZeroChar(char c) { EXPECT_NE(c, 0); }
FUZZ_TEST(DomainTest, TakeNonZeroChar).WithDomains(NonZeroChar());

void TakeNumericChar(char c) { EXPECT_TRUE(std::isdigit(c)); }
FUZZ_TEST(DomainTest, TakeNumericChar).WithDomains(NumericChar());

void TakeLowerChar(char c) { EXPECT_TRUE(std::islower(c)); }
FUZZ_TEST(DomainTest, TakeLowerChar).WithDomains(LowerChar());

void TakeUpperChar(char c) { EXPECT_TRUE(std::isupper(c)); }
FUZZ_TEST(DomainTest, TakeUpperChar).WithDomains(UpperChar());

void TakeAlphaChar(char c) { EXPECT_TRUE(std::isalpha(c)); }
FUZZ_TEST(DomainTest, TakeAlphaChar).WithDomains(AlphaChar());

void TakeAlphaNumericChar(char c) { EXPECT_TRUE(std::isalnum(c)); }
FUZZ_TEST(DomainTest, TakeAlphaNumericChar).WithDomains(AlphaNumericChar());

void TakePrintableAsciiChar(char c) { EXPECT_TRUE(std::isprint(c)); }
FUZZ_TEST(DomainTest, TakePrintableAsciiChar).WithDomains(PrintableAsciiChar());

void TakeAsciiChar(char c) {
  EXPECT_GE(c, 0);
  EXPECT_LE(c, 127);
}
FUZZ_TEST(DomainTest, TakeAsciiChar).WithDomains(AsciiChar());

////////////////////////////////////////////////////////////////
// Regular expression domains forwarded or stubbed from FuzzTest

// TODO: b/285775246 - Add support for `fuzztest::InRegexp`.
// void TakeMatch(std::string_view sv) {
//   ASSERT_EQ(sv.size(), 3U);
//   EXPECT_EQ(sv[0], 'a');
//   EXPECT_EQ(sv[2], 'c');
// }
// FUZZ_TEST(DomainTest, TakeMatch).WithDomains(InRegexp("a.c"));

////////////////////////////////////////////////////////////////
// Enumerated domains forwarded or stubbed from FuzzTest

void TakeSingleDigitEvenNumber(int n) {
  EXPECT_LT(n, 10);
  EXPECT_EQ(n % 2, 0);
}
FUZZ_TEST(DomainTest, TakeSingleDigitEvenNumber)
    .WithDomains(ElementOf({0, 2, 4, 6, 8}));

enum Flags : uint8_t {
  kFlag1 = 1 << 0,
  kFlag2 = 1 << 1,
  kFlag3 = 1 << 2,
};
void TakeFlagCombination(uint8_t flags) { EXPECT_FALSE(flags & Flags::kFlag2); }
FUZZ_TEST(DomainTest, TakeFlagCombination)
    .WithDomains(BitFlagCombinationOf({Flags::kFlag1, Flags::kFlag3}));

////////////////////////////////////////////////////////////////
// Aggregate domains forwarded or stubbed from FuzzTest

void TakeStructForTesting(const StructForTesting& obj) {
  EXPECT_NE(obj.a, 0);
  EXPECT_LT(obj.b, 0);
}
FUZZ_TEST(DomainTest, TakeStructForTesting)
    .WithDomains(StructOf<StructForTesting>(NonZero<int>(), Negative<long>()));

void TakeClassForTesting(const ClassForTesting& obj) {
  EXPECT_GE(obj.c(), kMin);
  EXPECT_LE(obj.c(), kMax);
  EXPECT_GE(obj.d(), 0);
}
FUZZ_TEST(DomainTest, TakeClassForTesting)
    .WithDomains(ConstructorOf<ClassForTesting>(InRange<unsigned char>(kMin,
                                                                       kMax),
                                                NonNegative<short>()));

void TakePair(const std::pair<char, float>& p) {
  EXPECT_TRUE(std::islower(p.first));
  EXPECT_TRUE(std::isfinite(p.second));
}
FUZZ_TEST(DomainTest, TakePair)
    .WithDomains(PairOf(LowerChar(), Finite<float>()));

void TakeTuple(std::tuple<short, int> a, long b) {
  EXPECT_NE(std::get<short>(a), 0);
  EXPECT_NE(std::get<int>(a), 0);
  EXPECT_NE(b, 0);
}
FUZZ_TEST(DomainTest, TakeTuple)
    .WithDomains(TupleOf(NonZero<short>(), NonZero<int>()), NonZero<long>());

void TakeVariant(const std::variant<int, long>&) {}
FUZZ_TEST(DomainTest, TakeVariant)
    .WithDomains(VariantOf(Arbitrary<int>(), Arbitrary<long>()));

void TakeOptional(const std::optional<int>&) {}
FUZZ_TEST(DomainTest, TakeOptional).WithDomains(OptionalOf(Arbitrary<int>()));

void TakeNullOpt(const std::optional<int>& option) { EXPECT_FALSE(option); }
FUZZ_TEST(DomainTest, TakeNullOpt).WithDomains(NullOpt<int>());

void TakeNonNull(const std::optional<int>& option) { EXPECT_TRUE(option); }
FUZZ_TEST(DomainTest, TakeNonNull)
    .WithDomains(NonNull(OptionalOf(Arbitrary<int>())));

////////////////////////////////////////////////////////////////
// Other miscellaneous domains forwarded or stubbed from FuzzTest

void TakePositiveOrMinusOne(int n) {
  if (n != -1) {
    EXPECT_GT(n, 0);
  }
}
FUZZ_TEST(DomainTest, TakePositiveOrMinusOne)
    .WithDomains(OneOf(Just(-1), Positive<int>()));

void TakePackedValue(uint32_t value) {
  EXPECT_GE(value & 0xFFFF, 1000U);
  EXPECT_LT(value >> 16, 2048U);
}
FUZZ_TEST(DomainTest, TakePackedValue)
    .WithDomains(
        Map([](uint16_t lower,
               uint16_t upper) { return (uint32_t(upper) << 16) | lower; },
            InRange<uint16_t>(1000U, std::numeric_limits<uint16_t>::max()),
            InRange<uint16_t>(0U, 2047U)));

void TakeOrdered(size_t x, size_t y) { EXPECT_LT(x, y); }
void FlatMapAdapter(const std::pair<size_t, size_t>& p) {
  TakeOrdered(p.first, p.second);
}
FUZZ_TEST(DomainTest, FlatMapAdapter)
    .WithDomains(FlatMap(
        [](size_t x) {
          return PairOf(
              Just(x),
              InRange<size_t>(x + 1, std::numeric_limits<size_t>::max()));
        },
        InRange<size_t>(0, std::numeric_limits<size_t>::max() - 1)));

void TakeEven(unsigned int n) { EXPECT_EQ(n % 2, 0U); }
FUZZ_TEST(DomainTest, TakeEven)
    .WithDomains(Filter([](unsigned int n) { return n % 2 == 0; },
                        Arbitrary<unsigned int>()));

////////////////////////////////////////////////////////////////
// pw_status-related types

void TakeStatus(const Status&) {}
FUZZ_TEST(ArbitraryTest, TakeStatus).WithDomains(Arbitrary<Status>());

void TakeStatusWithSize(const StatusWithSize&) {}
FUZZ_TEST(ArbitraryTest, TakeStatusWithSize)
    .WithDomains(Arbitrary<StatusWithSize>());

void TakeNonOkStatus(const Status& status) { EXPECT_FALSE(status.ok()); }
FUZZ_TEST(FilterTest, TakeNonOkStatus).WithDomains(NonOkStatus());

////////////////////////////////////////////////////////////////
// pw_result-related types

void TakeResult(const Result<int>&) {}
FUZZ_TEST(DomainTest, TakeResult).WithDomains(ResultOf(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeResult).WithDomains(Arbitrary<Result<int>>());

////////////////////////////////////////////////////////////////
// pw_containers-related types

void TakeVector(const Vector<int>& vector) {
  EXPECT_EQ(vector.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeVector)
    .WithDomains(VectorOf<kSize>(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeVector)
    .WithDomains(Arbitrary<Vector<int, kSize>>());

void TakeVectorAsContainer(const Vector<int>&) {}
FUZZ_TEST(ContainerTest, TakeVectorAsContainer)
    .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()));

void TakeVectorNonEmpty(const Vector<int>& vector) {
  EXPECT_FALSE(vector.empty());
}
FUZZ_TEST(ContainerTest, TakeVectorNonEmpty)
    .WithDomains(NonEmpty(ContainerOf<Vector<int, kSize>>(Arbitrary<int>())));

void TakeVectorLessThan3(const Vector<int>& vector) {
  EXPECT_LT(vector.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeVectorLessThan3)
    .WithDomains(
        ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMaxSize(2));

void TakeVectorAtLeast3(const Vector<int>& vector) {
  EXPECT_GE(vector.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeVectorAtLeast3)
    .WithDomains(
        ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMinSize(3));

void TakeVectorExactly3(const Vector<int>& vector) {
  EXPECT_EQ(vector.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeVectorExactly3)
    .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithSize(3));

void TakeVectorUnique(const Vector<int>& vector) {
  for (auto i = vector.begin(); i != vector.end(); ++i) {
    for (auto j = i + 1; j != vector.end(); ++j) {
      EXPECT_NE(*i, *j);
    }
  }
}
FUZZ_TEST(ContainerTest, TakeVectorUnique)
    .WithDomains(
        UniqueElementsContainerOf<Vector<int, kSize>>(Arbitrary<int>()));
FUZZ_TEST(DomainTest, TakeVectorUnique)
    .WithDomains(UniqueElementsVectorOf<kSize>(Arbitrary<int>()));

void TakeFlatMap(const containers::FlatMap<int, size_t, kSize>&) {}
FUZZ_TEST(DomainTest, TakeFlatMap)
    .WithDomains(FlatMapOf<kSize>(Arbitrary<int>(), Arbitrary<size_t>()));
FUZZ_TEST(ArbitraryTest, TakeFlatMap)
    .WithDomains(Arbitrary<containers::FlatMap<int, size_t, kSize>>());
FUZZ_TEST(ContainerTest, TakeFlatMap)
    .WithDomains(ContainerOf<containers::FlatMap<int, size_t, kSize>>(
        FlatMapPairOf(Arbitrary<int>(), Arbitrary<size_t>())));
FUZZ_TEST(MapToTest, TakeFlatMap)
    .WithDomains(MapToFlatMap<kSize>(
        UniqueElementsVectorOf<kSize>(Arbitrary<int>()).WithSize(kSize),
        ArrayOf<kSize>(Arbitrary<size_t>())));

void TakeDeque(const InlineDeque<int, kSize>& deque) {
  EXPECT_EQ(deque.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeDeque).WithDomains(DequeOf<kSize>(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeDeque)
    .WithDomains(Arbitrary<InlineDeque<int, kSize>>());

void TakeBasicDeque(const BasicInlineDeque<int, unsigned short, kSize>& deque) {
  EXPECT_EQ(deque.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeBasicDeque)
    .WithDomains(BasicDequeOf<unsigned short, kSize>(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeBasicDeque)
    .WithDomains(Arbitrary<BasicInlineDeque<int, unsigned short, kSize>>());

void TakeQueue(const InlineQueue<int, kSize>& queue) {
  EXPECT_EQ(queue.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeQueue).WithDomains(QueueOf<kSize>(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeQueue)
    .WithDomains(Arbitrary<InlineQueue<int, kSize>>());

void TakeBasicQueue(const BasicInlineQueue<int, unsigned short, kSize>& queue) {
  EXPECT_EQ(queue.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeBasicQueue)
    .WithDomains(BasicQueueOf<unsigned short, kSize>(Arbitrary<int>()));
FUZZ_TEST(ArbitraryTest, TakeBasicQueue)
    .WithDomains(Arbitrary<BasicInlineQueue<int, unsigned short, kSize>>());

// Test item that can be added to an intrusive list.
class TestItem : public IntrusiveList<TestItem>::Item {
 public:
  constexpr explicit TestItem(long value) : value_(value) {}
  long value() const { return value_; }

 private:
  long value_;
};

// IntrusiveLists cannot be generated directly, but ScopedLists can.
void TakeIntrusiveList(const IntrusiveList<TestItem>& list) {
  EXPECT_LE(list.size(), kSize);
}
void ScopedListAdapter(const ScopedList<TestItem, kSize>& scoped) {
  TakeIntrusiveList(scoped.list());
}
FUZZ_TEST(DomainTest, ScopedListAdapter)
    .WithDomains(ScopedListOf<TestItem, kSize>(Arbitrary<long>()));

////////////////////////////////////////////////////////////////
// pw_string-related types

void TakeString(const InlineString<>& string) {
  EXPECT_EQ(string.max_size(), kSize);
}
FUZZ_TEST(DomainTest, TakeString)
    .WithDomains(StringOf<kSize>(Arbitrary<char>()));
FUZZ_TEST(ArbitraryTest, TakeString)
    .WithDomains(Arbitrary<InlineString<kSize>>());
FUZZ_TEST(FilterTest, TakeString).WithDomains(String<kSize>());

void TakeStringAsContainer(const InlineString<>&) {}
FUZZ_TEST(ContainerTest, TakeStringAsContainer)
    .WithDomains(ContainerOf<InlineString<kSize>>(Arbitrary<char>()));

void TakeStringNonEmpty(const InlineString<>& string) {
  EXPECT_FALSE(string.empty());
}
FUZZ_TEST(ContainerTest, TakeStringNonEmpty)
    .WithDomains(NonEmpty(ContainerOf<InlineString<kSize>>(Arbitrary<char>())));

void TakeStringLessThan3(const InlineString<>& string) {
  EXPECT_LT(string.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeStringLessThan3)
    .WithDomains(
        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMaxSize(2));

void TakeStringAtLeast3(const InlineString<>& string) {
  EXPECT_GE(string.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeStringAtLeast3)
    .WithDomains(
        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMinSize(3));

void TakeStringExactly3(const InlineString<>& string) {
  EXPECT_EQ(string.size(), 3U);
}
FUZZ_TEST(ContainerTest, TakeStringExactly3)
    .WithDomains(
        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithSize(3));

void TakeAsciiString(const InlineString<>& string) {
  EXPECT_TRUE(std::all_of(
      string.begin(), string.end(), [](int c) { return c < 0x80; }));
}
FUZZ_TEST(FilterTest, TakeAsciiString).WithDomains(AsciiString<kSize>());

void TakePrintableAsciiString(const InlineString<>& string) {
  EXPECT_TRUE(std::all_of(string.begin(), string.end(), isprint));
}
FUZZ_TEST(FilterTest, TakePrintableAsciiString)
    .WithDomains(PrintableAsciiString<kSize>());

}  // namespace
}  // namespace pw::fuzzer
