// Copyright 2022 Google LLC
//
// 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 FUZZTEST_FUZZTEST_DOMAIN_H_
#define FUZZTEST_FUZZTEST_DOMAIN_H_

#include <array>
#include <cstdint>
#include <deque>
#include <initializer_list>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/random/bit_gen_ref.h"
#include "absl/random/random.h"
#include "absl/strings/str_format.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "./fuzztest/internal/absl_domain.h"
#include "./fuzztest/internal/any.h"
#include "./fuzztest/internal/domain.h"
#include "./fuzztest/internal/logging.h"
#include "./fuzztest/internal/meta.h"
#include "./fuzztest/internal/protobuf_domain.h"
#include "./fuzztest/internal/serialization.h"
#include "./fuzztest/internal/type_support.h"

namespace fuzztest {

// Type erased version of the domain concept.
// It can be constructed from any object that follows the domain concept for the
// right `value_type`. This class implements the domain concept too.
// TODO(sbenzaquen): Document the domain concept when it is stable enough.

template <typename T>
class Domain {
 public:
  using value_type = T;
  using corpus_type = internal::GenericDomainCorpusType;
  static constexpr bool has_custom_corpus_type = true;

  template <typename Inner>
  Domain(const internal::DomainBase<Inner, T>& inner)
      : inner_(new auto(static_cast<const Inner&>(inner))) {}

  Domain(const Domain& other) { *this = other; }
  Domain& operator=(const Domain& other) {
    inner_.reset(static_cast<internal::TypedDomainInterface<T>*>(
        other.inner_->Clone().release()));
    return *this;
  }
  // No default constructor or move operations to avoid a null state.

  // Init() generates a random value of corpus_type.
  //
  // The generated value can often be a "special value" (e.g., 0, MAX_INT, NaN,
  // infinity, empty vector, etc.). For basic, fixed sized data types (e.g.,
  // optional<int>) Init() might give any value. For variable-sized data types
  // (e.g., containers, linked lists, trees, etc) Init() typically returns a
  // smaller sized value. Larger sized values however can be created through
  // Mutate() calls.
  //
  // ENSURES: That Init() is non-deterministic, i.e., it doesn't always return
  // the same value. This is because Mutate() often relies on Init() giving
  // different values (e.g., when growing a std::set<T> and adding new T
  // values).
  corpus_type Init(absl::BitGenRef prng) { return inner_->UntypedInit(prng); }

  // Mutate() makes a relatively small modification on `val` of corpus_type.
  //
  // When `only_shrink` is enabled, the mutated value is always "simpler" (e.g.,
  // smaller).
  //
  // ENSURES: That the mutated value is not the same as the original.
  void Mutate(corpus_type& val, absl::BitGenRef prng, bool only_shrink) {
    return inner_->UntypedMutate(val, prng, only_shrink);
  }

  // Try to update the dynamic memory dictionary.
  // If it propagates to a domain that's compatible with dynamic
  // dictionary, it will try to match and save dictionary entries from
  // dynamic data collected by SanCov.
  void UpdateMemoryDictionary(const corpus_type& val) {
    return inner_->UntypedUpdateMemoryDictionary(val);
  }

  auto GetPrinter() const { return Printer{*inner_}; }

  value_type GetValue(const corpus_type& v) const {
    return inner_->TypedGetValue(v);
  }

  std::optional<corpus_type> FromValue(const value_type& v) const {
    return inner_->TypedFromValue(v);
  }

  std::optional<corpus_type> ParseCorpus(const internal::IRObject& obj) const {
    return inner_->UntypedParseCorpus(obj);
  }

  internal::IRObject SerializeCorpus(const corpus_type& v) const {
    return inner_->UntypedSerializeCorpus(v);
  }
  // TODO(JunyangShao): Get rid of this API so it won't be exposed
  // to outside.
  // Return the field counts of `val` if `val` is
  // a `ProtobufDomainImpl::corpus_type`. Otherwise propagate it
  // to inner domains and returns the sum of inner results.
  uint64_t CountNumberOfFields(const corpus_type& val) {
    return inner_->UntypedCountNumberOfFields(val);
  }

  // Mutate the selected protobuf field using `selected_field_index`.
  // Return value is the same as CountNumberOfFields.
  uint64_t MutateSelectedField(corpus_type& val, absl::BitGenRef prng,
                               bool only_shrink,
                               uint64_t selected_field_index) {
    return inner_->UntypedMutateSelectedField(val, prng, only_shrink,
                                              selected_field_index);
  }

  auto Clone() const { return inner_->Clone(); }

 private:
  // Have a subinterface just for the type traits to not expose more than
  // necessary through GetPrinter().
  friend class DomainBuilder;

  struct Printer {
    const internal::UntypedDomainInterface& inner;
    void PrintCorpusValue(const corpus_type& val, absl::FormatRawSink out,
                          internal::PrintMode mode) const {
      inner.UntypedPrintCorpusValue(val, out, mode);
    }
  };

  std::unique_ptr<internal::TypedDomainInterface<T>> inner_;
};

class DomainBuilder {
 public:
  DomainBuilder()
      : domain_lookup_table_(std::make_unique<DomainLookUpTable>()) {}

  DomainBuilder(const DomainBuilder&) = delete;
  DomainBuilder& operator=(const DomainBuilder&) = delete;

  // Return a domain referred by `name`. Such a domain doesn't know what type of
  // values it can handle until we call Set on the name.
  template <typename T>
  Domain<T> Get(std::string_view name) {
    FUZZTEST_INTERNAL_CHECK(domain_lookup_table_ != nullptr,
                            "Finalize() has been called!");
    return IndirectDomain<T>(GetIndirect<T>(name));
  }

  template <typename T>
  void Set(std::string_view name, const Domain<T>& domain) {
    FUZZTEST_INTERNAL_CHECK(domain_lookup_table_ != nullptr,
                            "Finalize() has been called!");
    auto* indirect = GetIndirect<T>(name);
    FUZZTEST_INTERNAL_CHECK(!indirect->has_value(),
                            "Cannot set the same domain twice!");
    *indirect = internal::MoveOnlyAny(std::in_place_type<Domain<T>>, domain);
  }

  // Return the top level domain that is used for generating and mutating
  // values. This is also the only domain that a user should actually use. We
  // should set every named domain in the builder before we call Finalize. And
  // after calling it, the domain builder is invalidated and cannot be used
  // anymore.
  template <typename T>
  Domain<T> Finalize(std::string_view name) && {
    FUZZTEST_INTERNAL_CHECK(domain_lookup_table_ != nullptr,
                            "Finalize() has been called!");
    FUZZTEST_INTERNAL_CHECK(
        GetIndirect<T>(name)->has_value(),
        // FUZZTEST_INTERNAL_CHECK uses absl::StrCat. But absl::StrCat does not
        // accept std::string_view in iOS builds, so convert to std::string.
        "Finalize() has been called with an unknown name: ", std::string(name));
    for (auto& iter : *domain_lookup_table_) {
      FUZZTEST_INTERNAL_CHECK(
          iter.second != nullptr && iter.second->has_value(),
          "Some domain is not set yet!");
    }
    return OwningDomain<T>(GetIndirect<T>(name)->template GetAs<Domain<T>>(),
                           std::move(domain_lookup_table_));
  }

 private:
  // We don't need copyability of the inner domains here.
  // We use shared_ptr to hold the whole table together.
  // The domains point into each other and into themselves recursively. We must
  // keep them with pointer stability.
  using DomainLookUpTable =
      absl::flat_hash_map<std::string, std::unique_ptr<internal::MoveOnlyAny>>;

  // Return the raw pointer of the indirections.
  template <typename T>
  auto GetIndirect(std::string_view name) {
    auto& indirection = (*domain_lookup_table_)[name];
    if (!indirection) {
      indirection = std::make_unique<internal::MoveOnlyAny>();
    }
    FUZZTEST_INTERNAL_CHECK(
        !indirection->has_value() || indirection->Has<Domain<T>>(),
        "The indirection must either be empty or hold a value of Domain<T>");
    return indirection.get();
  }

  // Domains that uses a layer of indirection. This allows us to create domains
  // for recursive data structures.
  template <typename T>
  class IndirectDomain : public internal::DomainBase<IndirectDomain<T>> {
   public:
    using value_type = typename Domain<T>::value_type;
    using corpus_type = typename Domain<T>::corpus_type;
    static constexpr bool has_custom_corpus_type = true;

    explicit IndirectDomain(internal::MoveOnlyAny* indirect)
        : indirect_inner_(indirect) {}

    corpus_type Init(absl::BitGenRef prng) {
      return GetInnerDomain().Init(prng);
    }

    void Mutate(corpus_type& val, absl::BitGenRef prng, bool only_shrink) {
      GetInnerDomain().Mutate(val, prng, only_shrink);
    }

    void UpdateMemoryDictionary(const corpus_type& val) {
      return GetInnerDomain().UpdateMemoryDictionary(val);
    }

    auto GetPrinter() const { return GetInnerDomain().GetPrinter(); }

    value_type GetValue(const corpus_type& v) const {
      return GetInnerDomain().GetValue(v);
    }

    std::optional<corpus_type> FromValue(const value_type& v) const {
      return GetInnerDomain().FromValue(v);
    }

    std::optional<corpus_type> ParseCorpus(
        const internal::IRObject& obj) const {
      return GetInnerDomain().ParseCorpus(obj);
    }

    internal::IRObject SerializeCorpus(const corpus_type& v) const {
      return GetInnerDomain().SerializeCorpus(v);
    }

   private:
    Domain<T>& GetInnerDomain() const {
      return indirect_inner_->GetAs<Domain<T>>();
    }
    internal::MoveOnlyAny* indirect_inner_;
  };

  // Same as Domain<T>, but also holds ownership of the lookup table.
  // This is for toplevel domains.
  template <typename T>
  class OwningDomain : public internal::DomainBase<OwningDomain<T>> {
   public:
    OwningDomain(const Domain<T>& inner,
                 std::unique_ptr<DomainLookUpTable> domain_lookup_table)
        : inner_(inner), domain_lookup_table_(std::move(domain_lookup_table)) {}

    using value_type = typename Domain<T>::value_type;
    using corpus_type = typename Domain<T>::corpus_type;
    static constexpr bool has_custom_corpus_type = true;

    corpus_type Init(absl::BitGenRef prng) { return inner_.Init(prng); }

    void Mutate(corpus_type& val, absl::BitGenRef prng, bool only_shrink) {
      inner_.Mutate(val, prng, only_shrink);
    }

    void UpdateMemoryDictionary(const corpus_type& val) {
      return inner_.UpdateMemoryDictionary(val);
    }

    auto GetPrinter() const { return inner_.GetPrinter(); }

    value_type GetValue(const corpus_type& v) const {
      return inner_.GetValue(v);
    }

    std::optional<corpus_type> FromValue(const value_type& v) const {
      return inner_.FromValue(v);
    }

    std::optional<corpus_type> ParseCorpus(
        const internal::IRObject& obj) const {
      return inner_.ParseCorpus(obj);
    }

    internal::IRObject SerializeCorpus(const corpus_type& v) const {
      return inner_.SerializeCorpus(v);
    }

   private:
    Domain<T> inner_;
    // Domains are copy constructible, so we need shared access to this table.
    std::shared_ptr<const DomainLookUpTable> domain_lookup_table_;
  };

  std::unique_ptr<DomainLookUpTable> domain_lookup_table_;
};

// This namespace is here only as a way to disable ADL (argument-dependent
// lookup). Names should be used from the fuzztest:: namespace.
namespace internal_no_adl {

// Arbitrary<T>() represents any value of type T.
//
// Example usage:
//
//   Arbitrary<int>()  // Any `int` value.
//
// The Arbitrary<T>() domain is implemented for all native C++ types and for
// protocol buffers. E.g.,:
//
//   Arbitrary<absl::flat_hash_map<uint32_t, MyProtoMessage>>()
//
template <typename T>
auto Arbitrary() {
  return internal::ArbitraryImpl<T>{};
}

// ElementOf(values) represents the input domain composed of the explicitly
// listed `values`.
//
// Example usage:
//
//   ElementOf({0xDEADBEEF, 0xBADDCAFE, 0xFEEDFACE})
//
template <typename T>
auto ElementOf(std::initializer_list<T> values) {
  return internal::ElementOfImpl<T>(values);
}

template <typename T>
auto ElementOf(std::vector<T> values) {
  return internal::ElementOfImpl<T>(std::move(values));
}

template <typename T>
auto Just(T val) {
  return internal::ElementOfImpl<T>({std::move(val)});
}

template <int&... ExplicitArgumentBarrier, typename... Inner>
auto OneOf(Inner... domains) {
  return internal::OneOfImpl<Inner...>(std::move(domains)...);
}

// Filter(predicate, inner) combinator creates a domain that filters out values
// with `predicate` from an `inner` domain.
//
// IMPORTANT: Use this only to filter out a small subset of the original domain,
// otherwise fuzzing won't be effective.
//
// Example usage:
//
//   Filter([](int x) { return x != kSentinel; }, Arbitrary<int>())
//
template <int&... ExplicitArgumentBarrier, typename Inner, typename Pred>
auto Filter(Pred predicate, Inner inner) {
  return internal::FilterImpl<Pred, Inner>(std::move(predicate),
                                           std::move(inner));
}

// InRange(min, max) represents any value between [min, max], closed interval.
// Supports integral and floating point types.
//
// Example usage:
//
//   InRange(0.0, 1.0)  // Any probability value.
//
template <typename T>
auto InRange(T min, T max) {
  return internal::InRangeImpl<T>(min, max);
}

// Finite() represents any floating point number, that is not infinite or NaN.
//
// Example usage:
//
//   Finite<double>()  // Any finite double.
//
template <typename T>
auto Finite() {
  static_assert(std::is_floating_point_v<T>,
                "Finite<T>() can only be used with floating point types!");
  return Filter([](T f) { return std::isfinite(f); }, Arbitrary<T>());
}

// Positive() represents any number greater than zero.
//
// Example usage:
//
//   Positive<float>()  // Any positive float value.
//
template <typename T>
auto Positive() {
  if constexpr (std::is_floating_point_v<T>) {
    return InRange<T>(std::numeric_limits<T>::denorm_min(),
                      std::numeric_limits<T>::max());
  } else {
    return InRange<T>(T{1}, std::numeric_limits<T>::max());
  }
}

// NonNegative() represents any number not smaller than zero.
//
// Example usage:
//
//   NonNegative<float>()
//
template <typename T>
auto NonNegative() {
  return InRange<T>(T{}, std::numeric_limits<T>::max());
}

// Negative() represents any number less than zero.
//
// Example usage:
//
//   Negative<float>()  // Any negative float value.
//
template <typename T>
auto Negative() {
  static_assert(!std::is_unsigned_v<T>,
                "Negative<T>() can only be used with with signed T-s! "
                "For char, consider using signed char.");
  if constexpr (std::is_floating_point_v<T>) {
    return InRange<T>(std::numeric_limits<T>::lowest(),
                      -std::numeric_limits<T>::denorm_min());
  } else {
    return InRange<T>(std::numeric_limits<T>::min(), T{-1});
  }
}

// NonPositive() represents any number not greater than zero.
//
// Example usage:
//
//   NonPositive<float>()
//
template <typename T>
auto NonPositive() {
  static_assert(!std::is_unsigned_v<T>,
                "NonPositive<T>() can only be used with with signed T-s! "
                "For char, consider using signed char.");
  return InRange<T>(std::numeric_limits<T>::lowest(), T{});
}

// NonZero() represents any number except zero.
//
// Example usage:
//
//   NonZero<float>()        // Any non-zero float value.
//
// If the type is unsigned, then the domain represents positive values. For
// example:
//
//   NonZero<unsigned int>() // Any positive int value.
//
template <typename T>
auto NonZero() {
  if constexpr (std::is_signed_v<T>) {
    return OneOf(Negative<T>(), Positive<T>());
  } else {
    return Positive<T>();
  }
}

// BitFlagCombinationOf(flags) represents any combination of binary `flags` via
// bitwise operations.
//
// Example usage:
//
//   enum Options {
//     kFirst  = 1 << 0,
//     kSecond = 1 << 1,
//     kThird  = 1 << 2,
//   };
//
//   BitFlagCombinationOf({kFirst, kThird})
//
// will includes {0, kFirst, kThird,  kFirst | kThird}.
template <typename T>
auto BitFlagCombinationOf(std::initializer_list<T> flags) {
  return internal::BitFlagCombinationOfImpl<T>(
      absl::MakeSpan(flags.begin(), flags.end()));
}

template <typename T>
auto BitFlagCombinationOf(const std::vector<T>& flags) {
  return internal::BitFlagCombinationOfImpl<T>(absl::MakeSpan(flags));
}

// ContainerOf<T>(inner) combinator creates a domain for a container T (eg, a
// std::vector, std::set, etc) where elements are created from `inner`.
//
// Example usage:
//
//   ContainerOf<std::vector<int>>(InRange(1, 2021))
//
// The domain also supports customizing the minimum and maximum size via the
// `WithSize`, `WithMinSize` and `WithMaxSize` functions. Eg:
//
//   ContainerOf<std::vector<int>>(Arbitrary<int>()).WithMaxSize(5)
//
template <typename T, int&... ExplicitArgumentBarrier, typename Inner>
auto ContainerOf(Inner inner) {
  static_assert(
      std::is_same_v<internal::DropConst<typename T::value_type>,
                     internal::DropConst<typename Inner::value_type>>);
  return internal::ContainerOfImpl<T, Inner>(std::move(inner));
}

// If the container type `T` is a class template whose first template parameter
// is the type of values stored in the container, and whose other template
// parameters, if any, are optional, the template parameters of `T` may be
// omitted, in which case `ContainerOf` will use the `value_type` of the
// `elements_domain` as the first template parameter for T. For example:
//
//   ContainerOf<std::vector>(Positive<int>()).WithSize(3);
//
template <template <typename, typename...> class T,
          int&... ExplicitArgumentBarrier, typename Inner,
          typename C = T<typename Inner::value_type>>
auto ContainerOf(Inner inner) {
  static_assert(
      std::is_same_v<internal::DropConst<typename C::value_type>,
                     internal::DropConst<typename Inner::value_type>>);
  return internal::ContainerOfImpl<C, Inner>(std::move(inner));
}

// ASCII character domains.
inline auto NonZeroChar() { return Positive<char>(); }
inline auto AsciiChar() { return InRange<char>(0, 127); }
inline auto PrintableAsciiChar() { return InRange<char>(32, 126); }
inline auto NumericChar() { return InRange<char>('0', '9'); }
inline auto LowerChar() { return InRange<char>('a', 'z'); }
inline auto UpperChar() { return InRange<char>('A', 'Z'); }
inline auto AlphaChar() { return OneOf(LowerChar(), UpperChar()); }
inline auto AlphaNumericChar() { return OneOf(AlphaChar(), NumericChar()); }

// String() is shorthand for Arbitrary<std::string>().
inline auto String() { return Arbitrary<std::string>(); }

// StringOf(inner) combinator creates a `std::string` domain with characters of
// the `inner` domain.
//
// Example usage:
//
//   StringOf(AsciiChar())
//
template <int&... ExplicitArgumentBarrier, typename Inner>
inline auto StringOf(Inner inner) {
  return ContainerOf<std::string>(std::move(inner));
}

// AsciiString() represents `std::string`-s composed of ASCII characters.
inline auto AsciiString() { return StringOf(AsciiChar()); }

// PrintableAsciiString() represents `std::string`-s composed of printable ASCII
// characters.
inline auto PrintableAsciiString() { return StringOf(PrintableAsciiChar()); }

// InRegexp(regexp) represents strings that are sentences of a given regular
// expression `regexp`. The regular expression can use any syntax accepted by
// RE2 (https://github.com/google/re2/wiki/Syntax).
//
// Example usage:
//
//   InRegexp("[0-9]{4}-[0-9]{2}-[0-9]{2}")  // Date-like strings.
//
inline auto InRegexp(std::string_view regex) {
  return internal::InRegexpImpl(regex);
}

// StructOf<T>(inner...) combinator creates a user-defined type `T` domain with
// fields of the `inner...` domains.
//
// Example usage:
//
//   struct Thing {
//     int id;
//     std::string name;
//   };
//
//   StructOf<MyType>(InRange(0, 10), Arbitrary<std::string>())
//
template <typename T, int&... ExplicitArgumentBarrier, typename... Inner>
auto StructOf(Inner... inner) {
  return internal::AggregateOfImpl<T, internal::RequireCustomCorpusType::kYes,
                                   Inner...>(std::in_place,
                                             std::move(inner)...);
}

// PairOf(inner1, inner2) combinator creates a `std::pair` domain where the
// first element is of `inner1` domain, and the second element is of `inner2`
// domain.
//
// Example usage:
//
//   PairOf(InRange(0, 10), Arbitrary<std::string>())
//
template <int&... ExplicitArgumentBarrier, typename Inner1, typename Inner2>
auto PairOf(Inner1 inner1, Inner2 inner2) {
  return internal::AggregateOfImpl<
      std::pair<typename Inner1::value_type, typename Inner2::value_type>,
      internal::RequireCustomCorpusType::kNo, Inner1, Inner2>(
      std::in_place, std::move(inner1), std::move(inner2));
}

// TupleOf(inner...) combinator creates a `std::tuple` domain with elements of
// `inner...` domains.
//
// Example usage:
//
//   TupleOf(InRange(0, 10), Arbitrary<std::string>())
//
template <int&... ExplicitArgumentBarrier, typename... Inner>
auto TupleOf(Inner... inner) {
  return internal::AggregateOfImpl<std::tuple<typename Inner::value_type...>,
                                   internal::RequireCustomCorpusType::kNo,
                                   Inner...>(std::in_place,
                                             std::move(inner)...);
}

// VariantOf(inner...) combinator creates a `std::variant` domain with elements
// of `inner...` domains.
//
// Example usage:
//
//   VariantOf(InRange(0, 10), Arbitrary<std::string>())
//
// VariantOf<T>(inner...) allows specifying a custom variant type `T`.
//
// Example usage:
//
//   VariantOf<absl::variant<int,std::string>>(InRange(0, 10),
//                                             Arbitrary<std::string>())
//
// `T` can be an instantiation of `std::variant` or any other class that matches
// its API. E.g., `absl::variant`.
template <typename T, int&... ExplicitArgumentBarrier, typename... Inner>
auto VariantOf(Inner... inner) {
  return internal::VariantOfImpl<T, Inner...>(std::in_place,
                                              std::move(inner)...);
}

template <int&... ExplicitArgumentBarrier, typename... Inner>
auto VariantOf(Inner... inner) {
  return VariantOf<std::variant<typename Inner::value_type...>>(
      std::move(inner)...);
}

// OptionalOf(inner) combinator creates a `std::optional` domain with the
// underlying value of the `inner` domain.
//
// Example usage:
//
//   OptionalOf(InRange(0, 10))
//
//
// OptionalOf<T>(inner) allows specifying a custom optional type `T`.
//
// Example usage:
//
//   OptionalOf<absl::optional<int>>(InRange(0, 10))
//
// `T` can be an instantiation of `std::optional` or any other class that
// matches its API. E.g., `absl::optional`.
template <typename T, int&... ExplicitArgumentBarrier, typename Inner>
auto OptionalOf(Inner inner) {
  return internal::OptionalOfImpl<T, Inner>(std::move(inner));
}

template <int&... ExplicitArgumentBarrier, typename Inner>
auto OptionalOf(Inner inner) {
  return OptionalOf<std::optional<typename Inner::value_type>>(
      std::move(inner));
}

// NullOpt<T>() creates an optional<T> domain with a single value std::nullopt.
template <typename T>
auto NullOpt() {
  return internal::OptionalOfImpl<std::optional<T>, internal::ArbitraryImpl<T>>(
             internal::ArbitraryImpl<T>())
      .SetAlwaysNull();
}

// NonNull(inner) excludes `std::nullopt` from `inner` which needs to be
// an optional domain.
//
// Example usage:
//
//   NonNull(OptionalOf(InRange(0, 10)))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto NonNull(Inner inner) {
  return inner.SetWithoutNull();
}

// SmartPointerOf<T>(inner) combinator creates a domain for a smart pointer type
// `T` to the object of `inner` domain.
//
// Example usage:
//
//   SmartPointerOf<std::unique_ptr<int>>(InRange(0, 10))
//
// The inner object will be created via `new` through the `inner` domain.
//
// Compatible with std::unique_ptr, std::shared_ptr, and other smart pointers of
// similar API. For std::unique_ptr and std::shared_ptr, use UniquePtrOf() and
// SharedPtrOf() instead.
template <typename Ptr, int&... ExplicitArgumentBarrier, typename Inner>
auto SmartPointerOf(Inner inner) {
  return internal::SmartPointerOfImpl<Ptr, Inner>(std::move(inner));
}

// UniquePtrOf(inner) combinator creates a `std::unique_ptr` domain with the
// pointed object of the `inner` domain.
//
// Example usage:
//
//   UniquePtrOf(InRange(0, 10))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto UniquePtrOf(Inner inner) {
  return SmartPointerOf<std::unique_ptr<typename Inner::value_type>>(
      std::move(inner));
}

// SharedPtrOf(inner) combinator creates a `std::shared_ptr` domain with the
// pointed object of the `inner` domain.
//
// Example usage:
//
//   SharedPtrOf(InRange(0, 10))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto SharedPtrOf(Inner inner) {
  return SmartPointerOf<std::shared_ptr<typename Inner::value_type>>(
      std::move(inner));
}

// Map(mapper, inner...) combinator creates a domain that uses the `mapper`
// function to map the values created by the `inner...` domains.
// Example usage:
//
//   Map([](int i) { return 2 * i; }, Arbitrary<int>())
//
template <int&... ExplicitArgumentBarrier, typename Mapper, typename... Inner>
auto Map(Mapper mapper, Inner... inner) {
  return internal::MapImpl<Mapper, Inner...>(std::move(mapper),
                                             std::move(inner)...);
}

// `FlatMap(flat_mapper, inner...)` combinator creates a domain that uses the
// `flat_mapper` function to map the values created by the `inner...` domains.
// Unlike `Map`, however, `FlatMap` maps these into a new _domain_, instead of
// into a value. This domain can then be used as an argument to a fuzz test, or
// to another domain. This can be useful for generating values that depend on
// each other. Example usage:
//
//   // Generate domain of two equal-sized strings
//   FlatMap(
//     [](int size) {
//       return PairOf(Arbitrary<std::string>().WithSize(size),
//                     Arbitrary<std::string>().WithSize(size)); },
//     InRange(0, 10));
//
template <int&... ExplicitArgumentBarrier, typename FlatMapper,
          typename... Inner>
auto FlatMap(FlatMapper flat_mapper, Inner... inner) {
  return internal::FlatMapImpl<FlatMapper, Inner...>(std::move(flat_mapper),
                                                     std::move(inner)...);
}

// VectorOf(inner) combinator creates a `std::vector` domain with elements of
// the `inner` domain.
//
// Example usage:
//
//   VectorOf(InRange(1, 2021))  // std::vector of years.
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto VectorOf(Inner inner) {
  return ContainerOf<std::vector<typename Inner::value_type>>(std::move(inner));
}

// DequeOf(inner) combinator creates a `std::deque` domain with elements of the
// `inner` domain.
//
// Example usage:
//
//   DequeOf(InRange(1, 2021))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto DequeOf(Inner inner) {
  return ContainerOf<std::deque<typename Inner::value_type>>(std::move(inner));
}

// ListOf(inner) combinator creates a `std::list` domain with elements of the
// `inner` domain.
//
// Example usage:
//
//   ListOf(InRange(1, 2021))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto ListOf(Inner inner) {
  return ContainerOf<std::list<typename Inner::value_type>>(std::move(inner));
}

// SetOf(inner) combinator creates a `std::set` domain with elements of the
// `inner` domain.
//
// Example usage:
//
//   SetOf(InRange(1, 2021))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto SetOf(Inner inner) {
  return ContainerOf<std::set<typename Inner::value_type>>(std::move(inner));
}

// MapOf(key_domain, value_domain) combinator creates a `std::map` domain with
// keys from the `key_domain` domain, and values from the `value_domain` domain.
//
// Example usage:
//
//   MapOf(InRange(1, 100), Arbitrary<std::string>())
//
template <int&... ExplicitArgumentBarrier, typename KeyDomain,
          typename ValueDomain>
auto MapOf(KeyDomain key_domain, ValueDomain value_domain) {
  return ContainerOf<std::map<typename KeyDomain::value_type,
                              typename ValueDomain::value_type>>(
      PairOf(std::move(key_domain), std::move(value_domain)));
}

// UnorderedSetOf(inner) combinator creates a `std::unordered_set` domain with
// elements of the `inner` domain.
//
// Example usage:
//
//   UnorderedSetOf(InRange(1, 2021))
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto UnorderedSetOf(Inner inner) {
  return ContainerOf<std::unordered_set<typename Inner::value_type>>(
      std::move(inner));
}

// UnorderedMapOf(key_domain, value_domain) combinator creates a
// `std::unordered_map` domain with keys from the `key_domain` domain, and
// values from the `value_domain` domain.
//
// Example usage:
//
//   UnorderedMapOf(InRange(1, 100), Arbitrary<std::string>())
//
template <int&... ExplicitArgumentBarrier, typename KeyDomain,
          typename ValueDomain>
auto UnorderedMapOf(KeyDomain key_domain, ValueDomain value_domain) {
  return ContainerOf<std::unordered_map<typename KeyDomain::value_type,
                                        typename ValueDomain::value_type>>(
      PairOf(std::move(key_domain), std::move(value_domain)));
}

// ArrayOf(inner...) combinator creates a `std::array` domain with N elements,
// one for each of the N domains of `inner...`. ArrayOf<N>(inner) is an overload
// for the case where a single domain `inner` generates values for all the `N`
// elements in the `std::array`.
//
// Example usage:
//
//   ArrayOf(InRange(1, 2021), InRange(1, 12))
//
// Generates `std::array<int, 2>` instances, where the values might represent
// year and month.
//
//   ArrayOf<3>(InRange(0.0, 1.0))
//
// Generates `std::array<double, 3>` instances, where the values might represent
// corrdinates in a unit cube.
//
template <int&... ExplicitArgumentBarrier, typename... Inner>
auto ArrayOf(Inner... inner) {
  static_assert(sizeof...(Inner) > 0,
                "ArrayOf can only be used to create a non-empty std::array.");
  // All value_types of inner domains must be the same, though they can have
  // different corpus_types.
  using value_type =
      typename std::tuple_element_t<0, std::tuple<Inner...>>::value_type;
  static_assert(std::conjunction_v<
                    std::is_same<value_type, typename Inner::value_type>...>,
                "All domains in a ArrayOf must have the same value_type.");
  return internal::AggregateOfImpl<std::array<value_type, sizeof...(Inner)>,
                                   internal::RequireCustomCorpusType::kNo,
                                   Inner...>(std::in_place,
                                             std::move(inner)...);
}

template <int N, int&... ExplicitArgumentBarrier, typename Inner>
auto ArrayOf(const Inner& inner) {
  static_assert(N > 0,
                "ArrayOf can only be used to create a non-empty std::array.");
  // Use the above specialization, passing (copying) `inner` N times.
  return internal::ApplyIndex<N>(
      [&](auto... I) { return ArrayOf(((void)I, inner)...); });
}

// UniqueElementsContainerOf(inner) combinator is similar to:
//
//   Map([](absl::flat_hash_set<value_type> unique_values) {
//        return T(unique_values.begin(), unique_values.end());
//     }, UnorderedSetOf(inner))
//
// Where `value_type` is the type of values produced by domain `inner`.
// UniqueElementsContainerOf creates an intermediate domain similar to:
//
//   ContainerOf<absl::flat_hash_set>(inner)
//
// That domain produces collections of instances of `value_type`, where each
// value in the collection is unique; this means that `value_type` must meet the
// type constraints necessary to create an instance of:
//
//   absl::flat_hash_set<value_type>
//
// Example usage:
//
//   UniqueElementsContainerOf<std::vector<int>>(InRange(1, 2021))
//
// The domain supports customizing the minimum and maximum size via the same
// functions as other container combinators: `WithSize`, `WithMinSize` and
// `WithMaxSize`. For example:
//
//   UniqueElementsContainerOf<std::vector<int>>(Arbitrary<int>()).WithSize(5)
//
template <typename T, int&... ExplicitArgumentBarrier, typename Inner>
auto UniqueElementsContainerOf(Inner inner) {
  static_assert(
      std::is_same_v<internal::DropConst<typename T::value_type>,
                     internal::DropConst<typename Inner::value_type>>);
  return internal::UniqueElementsContainerImpl<T, Inner>(std::move(inner));
}

// UniqueElementsVectorOf(inner) combinator is a shorthand for:
//
//   UniqueElementsContainerOf<std::vector<ElementT>>(inner)
//
// Where `ElementT` is the type of value produced by the domain `inner`.
//
// Example usage:
//
//   UniqueElementsVectorOf(InRange(1, 2021))
//
template <typename Inner>
auto UniqueElementsVectorOf(Inner inner) {
  return UniqueElementsContainerOf<std::vector<typename Inner::value_type>>(
      std::move(inner));
}

// ConstructorOf<T>(inner...) combinator creates a user-defined type `T` domain
// by passing values from the `inner...` domains to T's constructor.
//
// Example usage:
//
//   class Thing {
//    public:
//     Thing(int a, std::string b);
//   };
//
//   ConstructorOf<Thing>(InRange(0, 5), Arbitrary<std::string>())
//
template <typename T, int&... ExplicitArgumentBarrier, typename... Inner>
auto ConstructorOf(Inner... inner) {
  // TODO(sbenzaquen): Consider using a custom impl instead of Map for better
  // diagnostics.
  return internal::NamedMap(
      internal::GetTypeName<T>(),
      [](auto&&... args) { return T(std::forward<decltype(args)>(args)...); },
      std::move(inner)...);
}

// NonEmpty(inner) is shorthand for domain.WithMinSize(1).
//
// To represent any non-empty container one can use NonEmpty(), e.g.,
// NonEmpty(Arbitrary<std::vector<int>>()) or NonEmpty(VectorOf(String())).
//
// Example usage:
//
//   NonEmpty(String())
//
template <int&... ExplicitArgumentBarrier, typename Inner>
auto NonEmpty(Inner inner) {
  return inner.WithMinSize(1);
}

}  // namespace internal_no_adl

// Inject the names from internal_no_adl into fuzztest, without allowing for
// ADL. Note that an `inline` namespace would not have this effect (ie it would
// still allow ADL to trigger).
using namespace internal_no_adl;  // NOLINT

}  // namespace fuzztest

#endif  // FUZZTEST_FUZZTEST_DOMAIN_H_
