// 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 <algorithm>
#include <optional>
#include <string>
#include <utility>

#include "base/check.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/values.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/parsing_utils.h"
#include "components/attribution_reporting/source_registration_error.mojom.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"

namespace attribution_reporting {

namespace {

using ::attribution_reporting::mojom::SourceRegistrationError;

bool AggregationKeyIdHasValidLength(const std::string& key) {
  return key.size() <= AggregationKeys::kMaxBytesPerAggregationKeyId;
}

bool IsValid(const AggregationKeys::Keys& keys) {
  return keys.size() <= kMaxAggregationKeysPerSource &&
         std::ranges::all_of(keys, [](const auto& key) {
           return AggregationKeyIdHasValidLength(key.first);
         });
}

}  // namespace

// static
std::optional<AggregationKeys> AggregationKeys::FromKeys(Keys keys) {
  if (!IsValid(keys)) {
    return std::nullopt;
  }

  return AggregationKeys(std::move(keys));
}

// static
base::expected<AggregationKeys, SourceRegistrationError>
AggregationKeys::FromJSON(const base::Value* value) {
  if (!value) {
    return AggregationKeys();
  }

  const base::DictValue* dict = value->GetIfDict();
  if (!dict) {
    return base::unexpected(
        SourceRegistrationError::kAggregationKeysDictInvalid);
  }

  const size_t num_keys = dict->size();

  if (num_keys > kMaxAggregationKeysPerSource) {
    return base::unexpected(
        SourceRegistrationError::kAggregationKeysDictInvalid);
  }

  Keys::container_type keys;
  keys.reserve(num_keys);

  for (auto [key_id, maybe_string_value] : *dict) {
    if (!AggregationKeyIdHasValidLength(key_id)) {
      return base::unexpected(
          SourceRegistrationError::kAggregationKeysKeyTooLong);
    }

    ASSIGN_OR_RETURN(
        absl::uint128 key, ParseAggregationKeyPiece(maybe_string_value),
        [](std::monostate) {
          return SourceRegistrationError::kAggregationKeysValueInvalid;
        });

    keys.emplace_back(key_id, key);
  }

  return AggregationKeys(Keys(base::sorted_unique, std::move(keys)));
}

AggregationKeys::AggregationKeys(Keys keys) : keys_(std::move(keys)) {
  CHECK(IsValid(keys_));
}

AggregationKeys::AggregationKeys() = default;

AggregationKeys::~AggregationKeys() = default;

AggregationKeys::AggregationKeys(const AggregationKeys&) = default;

AggregationKeys::AggregationKeys(AggregationKeys&&) = default;

AggregationKeys& AggregationKeys::operator=(const AggregationKeys&) = default;

AggregationKeys& AggregationKeys::operator=(AggregationKeys&&) = default;

base::DictValue AggregationKeys::ToJson() const {
  base::DictValue dict;
  for (const auto& [key, value] : keys_) {
    dict.Set(key, HexEncodeAggregationKey(value));
  }
  return dict;
}

}  // namespace attribution_reporting
