// Copyright 2022 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/aggregation_keys.h"

#include <stddef.h>

#include <string>
#include <utility>

#include "base/test/gmock_expected_support.h"
#include "base/test/values_test_util.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/source_registration_error.mojom.h"
#include "components/attribution_reporting/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"

namespace attribution_reporting {
namespace {

using ::attribution_reporting::mojom::SourceRegistrationError;
using ::base::test::ErrorIs;
using ::base::test::ValueIs;
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::Property;

TEST(AggregationKeysTest, FromJSON) {
  EXPECT_THAT(AggregationKeys::FromJSON(nullptr),
              ValueIs(Property(&AggregationKeys::keys, IsEmpty())));

  const struct {
    const char* description;
    const char* json;
    ::testing::Matcher<base::expected<AggregationKeys, SourceRegistrationError>>
        matches;
  } kTestCases[] = {
      {
          "Not a dictionary",
          "[]",
          ErrorIs(SourceRegistrationError::kAggregationKeysDictInvalid),
      },
      {
          "key not a string",
          R"({"key":123})",
          ErrorIs(SourceRegistrationError::kAggregationKeysValueInvalid),
      },
      {
          "key doesn't start with 0x",
          R"({"key":"159"})",
          ErrorIs(SourceRegistrationError::kAggregationKeysValueInvalid),
      },
      {
          "Invalid key",
          R"({"key":"0xG59"})",
          ErrorIs(SourceRegistrationError::kAggregationKeysValueInvalid),
      },
      {
          "One valid key",
          R"({"key":"0x159"})",
          ValueIs(Property(
              &AggregationKeys::keys,
              ElementsAre(
                  Pair("key", absl::MakeUint128(/*high=*/0, /*low=*/345))))),
      },
      {
          "Two valid keys",
          R"({"key1":"0x159","key2":"0x50000000000000159"})",
          ValueIs(Property(
              &AggregationKeys::keys,
              ElementsAre(
                  Pair("key1", absl::MakeUint128(/*high=*/0, /*low=*/345)),
                  Pair("key2", absl::MakeUint128(/*high=*/5, /*low=*/345))))),
      },
      {
          "Second key invalid",
          R"({"key1":"0x159","key2":""})",
          ErrorIs(SourceRegistrationError::kAggregationKeysValueInvalid),
      },
  };

  for (const auto& test_case : kTestCases) {
    SCOPED_TRACE(test_case.description);
    base::Value value = base::test::ParseJson(test_case.json);
    EXPECT_THAT(AggregationKeys::FromJSON(&value), test_case.matches);
  }
}

TEST(AggregationKeysTest, FromJSON_CheckSize) {
  struct TestCase {
    const char* description;
    bool valid;
    size_t key_count;
    size_t key_size;

    base::Value::Dict GetHeader() const {
      base::Value::Dict dict;
      for (size_t i = 0u; i < key_count; ++i) {
        dict.Set(GetKey(i), "0x1");
      }
      return dict;
    }

   private:
    std::string GetKey(size_t index) const {
      // Note that this might not be robust as
      // `attribution_reporting::kMaxAggregationKeysPerSource` varies
      // which might generate invalid JSON.
      return std::string(key_size, 'A' + index % 26 + 32 * (index / 26));
    }
  };

  const TestCase kTestCases[] = {
      {"empty", true, 0, 0},
      {"max_keys", true, kMaxAggregationKeysPerSource, 1},
      {"too_many_keys", false, kMaxAggregationKeysPerSource + 1, 1},
      {"max_key_size", true, 1, AggregationKeys::kMaxBytesPerAggregationKeyId},
      {"excessive_key_size", false, 1,
       AggregationKeys::kMaxBytesPerAggregationKeyId + 1},
  };

  for (const auto& test_case : kTestCases) {
    SCOPED_TRACE(test_case.description);
    base::Value value(test_case.GetHeader());
    EXPECT_EQ(AggregationKeys::FromJSON(&value).has_value(), test_case.valid);
  }
}

TEST(AggregationKeysTest, ToJson) {
  const struct {
    AggregationKeys input;
    const char* expected_json;
  } kTestCases[] = {
      {
          AggregationKeys(),
          R"json({})json",
      },
      {
          *AggregationKeys::FromKeys({{"a", 1}, {"b", 15}}),
          R"json({"a":"0x1","b":"0xf"})json",
      },
  };

  for (const auto& test_case : kTestCases) {
    EXPECT_THAT(test_case.input.ToJson(),
                base::test::IsJson(test_case.expected_json));
  }
}

}  // namespace
}  // namespace attribution_reporting
