// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/attribution_reporting/fuzz_utils.h"

#include <stddef.h>
#include <stdint.h>

#include <optional>
#include <string>
#include <utility>

#include "base/check.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/filters.h"
#include "components/attribution_reporting/max_event_level_reports.h"
#include "components/attribution_reporting/source_type.mojom-shared.h"
#include "third_party/fuzztest/src/fuzztest/fuzztest.h"

namespace attribution_reporting {

namespace {

fuzztest::Domain<std::string> AnyFilterString(std::optional<size_t> max_size) {
  auto string = fuzztest::Arbitrary<std::string>();
  if (max_size.has_value()) {
    string.WithMaxSize(*max_size);
  }

  return fuzztest::Filter(
      [](const std::string& s) {
        return base::IsStringUTF8AllowingNoncharacters(s);
      },
      std::move(string));
}

template <typename KeyPred>
fuzztest::Domain<FilterValues> AnyFilterValues(
    const fuzztest::Domain<std::string>& string,
    KeyPred&& key_pred,
    std::optional<size_t> max_values_per_key,
    std::optional<size_t> max_keys) {
  auto values_per_key = fuzztest::UniqueElementsVectorOf(string);
  if (max_values_per_key.has_value()) {
    values_per_key.WithMaxSize(*max_values_per_key);
  }

  auto key_values = fuzztest::ContainerOf<FilterValues>(
      fuzztest::PairOf(fuzztest::Filter(std::move(key_pred), string),
                       std::move(values_per_key)));
  if (max_keys.has_value()) {
    key_values.WithMaxSize(*max_keys);
  }

  return key_values;
}

fuzztest::Domain<base::TimeDelta> AnyLookbackWindow() {
  return fuzztest::Map(
      [](int64_t micros) { return base::Microseconds(micros); },
      fuzztest::Positive<int64_t>());
}

}  // namespace

fuzztest::Domain<mojom::SourceType> AnySourceType() {
  return fuzztest::ElementOf<mojom::SourceType>({
      mojom::SourceType::kNavigation,
      mojom::SourceType::kEvent,
  });
}

fuzztest::Domain<MaxEventLevelReports> AnyMaxEventLevelReports() {
  return fuzztest::ConstructorOf<MaxEventLevelReports>(
      fuzztest::InRange(0, static_cast<int>(MaxEventLevelReports::Max())));
}

fuzztest::Domain<FilterData> AnyFilterData() {
  return fuzztest::Map(
      [](const FilterValues& filter_values) {
        auto result = FilterData::CreateForTesting(filter_values);
        CHECK(result.has_value()) << static_cast<int>(result.error()) << ": "
                                  << FilterValuesToJson(filter_values);
        return *std::move(result);
      },
      AnyFilterValues(
          AnyFilterString(kMaxBytesPerFilterString),
          [](const std::string& key) {
            return key != FilterData::kSourceTypeFilterKey;
          },
          kMaxValuesPerFilter, kMaxFiltersPerSource));
}

fuzztest::Domain<FilterConfig> AnyFilterConfig() {
  return fuzztest::Map(
      [](FilterValues&& filter_values,
         std::optional<base::TimeDelta> lookback_window) {
        return *FilterConfig::Create(std::move(filter_values), lookback_window);
      },
      AnyFilterValues(
          AnyFilterString(/*max_size=*/std::nullopt),
          [](const std::string& key) {
            return !base::StartsWith(key, FilterConfig::kReservedKeyPrefix);
          },
          /*max_values_per_key=*/std::nullopt,
          /*max_keys=*/std::nullopt),
      fuzztest::OptionalOf(AnyLookbackWindow()));
}

fuzztest::Domain<FiltersDisjunction> AnyFiltersDisjunction() {
  return fuzztest::VectorOf(AnyFilterConfig());
}

fuzztest::Domain<FilterPair> AnyFilterPair() {
  return fuzztest::ConstructorOf<FilterPair>(
      /*positive=*/AnyFiltersDisjunction(),
      /*negative=*/AnyFiltersDisjunction());
}

}  // namespace attribution_reporting
