// 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_CORE_H_
#define FUZZTEST_FUZZTEST_DOMAIN_CORE_H_

#include <array>
#include <cmath>
#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/any.h"
#include "./fuzztest/internal/domains/aggregate_of_impl.h"
#include "./fuzztest/internal/domains/arbitrary_impl.h"
#include "./fuzztest/internal/domains/bit_flag_combination_of_impl.h"
#include "./fuzztest/internal/domains/container_of_impl.h"
#include "./fuzztest/internal/domains/domain_base.h"
#include "./fuzztest/internal/domains/element_of_impl.h"
#include "./fuzztest/internal/domains/filter_impl.h"
#include "./fuzztest/internal/domains/flat_map_impl.h"
#include "./fuzztest/internal/domains/in_range_impl.h"
#include "./fuzztest/internal/domains/map_impl.h"
#include "./fuzztest/internal/domains/one_of_impl.h"
#include "./fuzztest/internal/domains/optional_of_impl.h"
#include "./fuzztest/internal/domains/smart_pointer_of_impl.h"
#include "./fuzztest/internal/domains/unique_elements_container_of_impl.h"
#include "./fuzztest/internal/domains/variant_of_impl.h"
#include "./fuzztest/internal/logging.h"
#include "./fuzztest/internal/meta.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;

  // Intentionally not marked as explicit to allow implicit conversion from the
  // internal domain implementations.
  template <int&... ExplicitArgumentBarrier, typename Inner,
            typename CorpusType>
  Domain(const internal::DomainBase<Inner, T, CorpusType>& 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);
  }

  // Parses corpus value _without validating it_. Validation must be done with
  // ValidateCorpusValue().
  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);
  }

  // After creating a corpus value, either via ParseCorpus() or via FromValue()
  // this method is used to determine if the corpus value is valid.
  bool ValidateCorpusValue(const corpus_type& corpus_value) const {
    return inner_->UntypedValidateCorpusValue(corpus_value);
  }

  // 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>,
                                    internal::value_type_t<Domain<T>>,
                                    internal::corpus_type_t<Domain<T>>> {
   public:
    using typename IndirectDomain::DomainBase::corpus_type;
    using typename IndirectDomain::DomainBase::value_type;

    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);
    }

    bool ValidateCorpusValue(const corpus_type& corpus_value) const {
      return GetInnerDomain().ValidateCorpusValue(corpus_value);
    }

   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>,
                                    internal::value_type_t<Domain<T>>,
                                    internal::corpus_type_t<Domain<T>>> {
   public:
    using typename OwningDomain::DomainBase::corpus_type;
    using typename OwningDomain::DomainBase::value_type;

    OwningDomain(const Domain<T>& inner,
                 std::unique_ptr<DomainLookUpTable> domain_lookup_table)
        : inner_(inner), domain_lookup_table_(std::move(domain_lookup_table)) {}

    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);
    }

    bool ValidateCorpusValue(const corpus_type& corpus_value) const {
      return inner_.ValidateCorpusValue(corpus_value);
    }

   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<internal::value_type_t<T>>,
                     internal::DropConst<internal::value_type_t<Inner>>>);
  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<internal::value_type_t<Inner>>>
auto ContainerOf(Inner inner) {
  static_assert(
      std::is_same_v<internal::DropConst<internal::value_type_t<C>>,
                     internal::DropConst<internal::value_type_t<Inner>>>);
  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()); }

// 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<internal::value_type_t<Inner1>, internal::value_type_t<Inner2>>,
      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<internal::value_type_t<Inner>...>,
                                   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<internal::value_type_t<Inner>...>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<Inner>>>(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<internal::value_type_t<KeyDomain>,
                              internal::value_type_t<ValueDomain>>>(
      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<internal::value_type_t<Inner>>>(
      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<internal::value_type_t<KeyDomain>,
                                        internal::value_type_t<ValueDomain>>>(
      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 =
      internal::value_type_t<std::tuple_element_t<0, std::tuple<Inner...>>>;
  static_assert(std::conjunction_v<
                    std::is_same<value_type, internal::value_type_t<Inner>>...>,
                "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<internal::value_type_t<T>>,
                     internal::DropConst<internal::value_type_t<Inner>>>);
  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<internal::value_type_t<Inner>>>(
      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_CORE_H_
