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

#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"

#include <random>

#include "base/check.h"
#include "base/compiler_specific.h"
#include "base/no_destructor.h"
#include "base/optional.h"
#include "base/rand_util.h"
#include "base/synchronization/atomic_flag.h"
#include "base/threading/sequence_local_storage_slot.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings_provider.h"

namespace blink {

namespace {

// IdentifiabilityStudySettings is meant to be used as a global singleton. Its
// use is subject to the following constraints.
//
//   1. The embedder should be able to set the
//      IdentifiabilityStudySettingsProvider at any point during execution. This
//      relaxation allows the embedder to perform any required initialization
//      without blocking process startup.
//
//   2. Get() and the returned IdentifiabilityStudySettings instance should be
//      usable from any thread. The returned object must always be well
//      formed with an infinite lifetime.
//
//   3. Calling Get() "prior" to the embedder calling SetProvider() should be
//      harmless and non-blocking.
//
//   4. Be fast.
class ThreadsafeSettingsWrapper {
 public:
  ThreadsafeSettingsWrapper() = default;

  const IdentifiabilityStudySettings* GetSettings() {
    // Access to initialized_settings_ is behind a memory barrier used for
    // accessing the atomic flag |initialized_|. The state of
    // |initialized_settings_| is consistent due to the acquire-release
    // semantics enforced by |AtomicFlag|. I.e. writes prior to
    // AtomicFlag::Set() is visible after a AtomicFlag::IsSet() which returns
    // true.
    //
    // If the flag is not set, then |default_settings_| can be used instead.
    //
    // In either case, the returned pointer...
    //   1. ... Points to a well formed IdentifiabilityStudySettings object.
    //   2. ... Is valid for the remainder of the process lifetime.
    //   3. ... Is safe to use from any thread.
    if (!initialized_.IsSet())
      return &default_settings_;
    return &initialized_settings_.value();
  }

  // Same restrictions as IdentifiabilityStudySettings::SetGlobalProvider().
  void SetProvider(
      std::unique_ptr<IdentifiabilityStudySettingsProvider> provider) {
    DCHECK(!initialized_.IsSet());
    initialized_settings_.emplace(std::move(provider));
    initialized_.Set();
  }

  void ResetStateForTesting() {
    initialized_settings_.reset();
    initialized_.UnsafeResetForTesting();
  }

  // Function local static initializer is initialized in a threadsafe manner.
  // This object itself is cheap to construct.
  static ThreadsafeSettingsWrapper* GetWrapper() {
    static base::NoDestructor<ThreadsafeSettingsWrapper> wrapper;
    return wrapper.get();
  }

 private:
  base::Optional<IdentifiabilityStudySettings> initialized_settings_;
  const IdentifiabilityStudySettings default_settings_;
  base::AtomicFlag initialized_;
};

// RandGenerator de-biasing implementation stolen from //base/rand_util.h, and
// adapted to work with passed-in RNGs.
template <typename G>
uint64_t RandGenerator(uint64_t range, G& generator) {
  DCHECK_GT(range, 0u);
  // We must discard random results above this number, as they would
  // make the random generator non-uniform (consider e.g. if
  // MAX_UINT64 was 7 and |range| was 5, then a result of 1 would be twice
  // as likely as a result of 3 or 4).
  uint64_t max_acceptable_value =
      (std::numeric_limits<uint64_t>::max() / range) * range - 1;

  uint64_t value;
  do {
    value = generator();
  } while (value > max_acceptable_value);

  return value % range;
}

bool DecideSample(int sample_rate) {
  static base::NoDestructor<base::SequenceLocalStorageSlot<std::mt19937_64>>
      prng;

  if (sample_rate == 0)
    return false;

  if (sample_rate == 1)
    return true;

  if (!prng->GetValuePointer())
    prng->emplace(base::RandUint64());

  return RandGenerator(sample_rate, **prng) == 0;
}

}  // namespace

IdentifiabilityStudySettingsProvider::~IdentifiabilityStudySettingsProvider() =
    default;

IdentifiabilityStudySettings::IdentifiabilityStudySettings() = default;

IdentifiabilityStudySettings::IdentifiabilityStudySettings(
    std::unique_ptr<IdentifiabilityStudySettingsProvider> provider)
    : provider_(std::move(provider)),
      is_enabled_(provider_->IsActive()),
      is_any_surface_or_type_blocked_(provider_->IsAnyTypeOrSurfaceBlocked()) {}

IdentifiabilityStudySettings::~IdentifiabilityStudySettings() = default;

// static
const IdentifiabilityStudySettings* IdentifiabilityStudySettings::Get() {
  return ThreadsafeSettingsWrapper::GetWrapper()->GetSettings();
}

// static
void IdentifiabilityStudySettings::SetGlobalProvider(
    std::unique_ptr<IdentifiabilityStudySettingsProvider> provider) {
  ThreadsafeSettingsWrapper::GetWrapper()->SetProvider(std::move(provider));
}

void IdentifiabilityStudySettings::ResetStateForTesting() {
  ThreadsafeSettingsWrapper::GetWrapper()->ResetStateForTesting();
}

bool IdentifiabilityStudySettings::IsActive() const {
  return is_enabled_;
}

bool IdentifiabilityStudySettings::IsSurfaceAllowed(
    IdentifiableSurface surface) const {
  if (LIKELY(!is_enabled_))
    return false;

  if (LIKELY(!is_any_surface_or_type_blocked_))
    return true;

  return provider_->IsSurfaceAllowed(surface);
}

bool IdentifiabilityStudySettings::IsTypeAllowed(
    IdentifiableSurface::Type type) const {
  if (LIKELY(!is_enabled_))
    return false;

  if (LIKELY(!is_any_surface_or_type_blocked_))
    return true;

  return provider_->IsTypeAllowed(type);
}

bool IdentifiabilityStudySettings::IsWebFeatureAllowed(
    mojom::WebFeature feature) const {
  return IsSurfaceAllowed(IdentifiableSurface::FromTypeAndToken(
      IdentifiableSurface::Type::kWebFeature, feature));
}

bool IdentifiabilityStudySettings::ShouldSample(
    IdentifiableSurface surface) const {
  if (LIKELY(!is_enabled_))
    return false;

  return DecideSample(provider_->SampleRate(surface));
}

bool IdentifiabilityStudySettings::ShouldSample(
    IdentifiableSurface::Type type) const {
  if (LIKELY(!is_enabled_))
    return false;

  return DecideSample(provider_->SampleRate(type));
}

}  // namespace blink
