// Copyright 2018 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 "components/subresource_filter/content/common/ad_delay_throttle.h"

#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
#include "components/subresource_filter/core/common/common_features.h"
#include "url/gurl.h"
#include "url/url_constants.h"

namespace subresource_filter {

namespace {

void LogSecureInfo(AdDelayThrottle::SecureInfo info) {
  UMA_HISTOGRAM_ENUMERATION("SubresourceFilter.AdDelay.SecureInfo", info);
}

class InsecureCondition : public AdDelayThrottle::DeferCondition {
 public:
  InsecureCondition(base::TimeDelta delay,
                    AdDelayThrottle::MetadataProvider* provider)
      : DeferCondition(delay, provider) {}
  ~InsecureCondition() override {
    if (provider()->IsAdRequest()) {
      LogSecureInfo(was_condition_ever_satisfied()
                        ? AdDelayThrottle::SecureInfo::kInsecureAd
                        : AdDelayThrottle::SecureInfo::kSecureAd);
    } else {
      LogSecureInfo(was_condition_ever_satisfied()
                        ? AdDelayThrottle::SecureInfo::kInsecureNonAd
                        : AdDelayThrottle::SecureInfo::kSecureNonAd);
    }
  }

 private:
  // DeferCondition:
  bool IsConditionSatisfied(const GURL& url) override {
    // Note: this should probably be using content::IsOriginSecure which
    // accounts for things like whitelisted origins, localhost, etc. This isn't
    // used here because that function is quite expensive for insecure schemes,
    // involving many allocations and string scans.
    return url.SchemeIs(url::kHttpScheme);
  }
};

class NonIsolatedCondition : public AdDelayThrottle::DeferCondition {
 public:
  NonIsolatedCondition(base::TimeDelta delay,
                       AdDelayThrottle::MetadataProvider* provider)
      : DeferCondition(delay, provider) {}
  ~NonIsolatedCondition() override {
    if (provider()->IsAdRequest()) {
      UMA_HISTOGRAM_ENUMERATION(
          "SubresourceFilter.AdDelay.IsolatedInfo",
          was_condition_ever_satisfied()
              ? AdDelayThrottle::IsolatedInfo::kNonIsolatedAd
              : AdDelayThrottle::IsolatedInfo::kIsolatedAd);
    }
  }

 private:
  // DeferCondition:
  bool IsConditionSatisfied(const GURL& url) override {
    return provider()->RequestIsInNonIsolatedSubframe();
  }
};

};  // namespace

AdDelayThrottle::DeferCondition::DeferCondition(
    base::TimeDelta delay,
    AdDelayThrottle::MetadataProvider* provider)
    : delay_(delay), provider_(provider) {
  DCHECK(provider);
}
AdDelayThrottle::DeferCondition::~DeferCondition() = default;

bool AdDelayThrottle::DeferCondition::ShouldDefer(const GURL& url) {
  if (was_condition_applied_) {
    DCHECK(was_condition_ever_satisfied_);
    return false;
  }
  was_condition_ever_satisfied_ |= IsConditionSatisfied(url);
  return was_condition_ever_satisfied_;
}

// The request will be deferred. Returns the amount of time to defer.
base::TimeDelta AdDelayThrottle::DeferCondition::OnReadyToDefer() {
  DCHECK(!was_condition_applied_);
  DCHECK(was_condition_ever_satisfied_);
  was_condition_applied_ = true;
  return delay_;
}

constexpr base::TimeDelta AdDelayThrottle::kDefaultDelay;

AdDelayThrottle::Factory::Factory()
    : insecure_delay_(base::TimeDelta::FromMilliseconds(
          base::GetFieldTrialParamByFeatureAsInt(
              kDelayUnsafeAds,
              kInsecureDelayParam,
              kDefaultDelay.InMilliseconds()))),
      non_isolated_delay_(base::TimeDelta::FromMilliseconds(
          base::GetFieldTrialParamByFeatureAsInt(
              kDelayUnsafeAds,
              kNonIsolatedDelayParam,
              kDefaultDelay.InMilliseconds()))),
      delay_enabled_(base::FeatureList::IsEnabled(kAdTagging) &&
                     base::FeatureList::IsEnabled(kDelayUnsafeAds)) {}

AdDelayThrottle::Factory::~Factory() = default;

std::unique_ptr<AdDelayThrottle> AdDelayThrottle::Factory::MaybeCreate(
    std::unique_ptr<AdDelayThrottle::MetadataProvider> provider) const {
  DCHECK(provider);
  return base::WrapUnique(new AdDelayThrottle(std::move(provider), this));
}

AdDelayThrottle::~AdDelayThrottle() {
  if (!expected_delay_.is_zero()) {
    UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay", actual_delay_);
    UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay.Expected",
                        expected_delay_);
    UMA_HISTOGRAM_TIMES("SubresourceFilter.AdDelay.Delay.Queuing",
                        actual_delay_ - expected_delay_);
  }
}

void AdDelayThrottle::DetachFromCurrentSequence() {
  // The throttle is moving to another thread. Ensure this is done before any
  // weak pointers are created.
  DCHECK(!weak_factory_.HasWeakPtrs());
}

void AdDelayThrottle::WillStartRequest(network::ResourceRequest* request,
                                       bool* defer) {
  *defer = MaybeDefer(request->url);
}

void AdDelayThrottle::WillRedirectRequest(
    const net::RedirectInfo& redirect_info,
    const network::ResourceResponseHead& response_head,
    bool* defer,
    std::vector<std::string>* to_be_removed_headers) {
  // Note: some MetadataProviders may not be able to distinguish requests that
  // are only tagged as ads after a redirect.
  *defer = MaybeDefer(redirect_info.new_url);
}

bool AdDelayThrottle::MaybeDefer(const GURL& url) {
  // Check for condition matching before checking if the feature is enabled, to
  // ensure metrics can be reported.
  std::vector<DeferCondition*> matched_conditions;
  for (auto& condition : defer_conditions_) {
    if (condition->ShouldDefer(url))
      matched_conditions.push_back(condition.get());
  }

  if (!delay_enabled_ || matched_conditions.empty() ||
      !provider_->IsAdRequest()) {
    return false;
  }

  base::TimeDelta delay;
  for (DeferCondition* condition : matched_conditions) {
    delay += condition->OnReadyToDefer();
  }
  // TODO(csharrison): Consider logging to the console here that Chrome
  // delayed this request.
  expected_delay_ += delay;
  base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&AdDelayThrottle::Resume, weak_factory_.GetWeakPtr(),
                     tick_clock_->NowTicks()),
      delay);
  return true;
}

void AdDelayThrottle::Resume(base::TimeTicks defer_start) {
  actual_delay_ += tick_clock_->NowTicks() - defer_start;
  delegate_->Resume();
}

AdDelayThrottle::AdDelayThrottle(std::unique_ptr<MetadataProvider> provider,
                                 const AdDelayThrottle::Factory* factory)
    : provider_(std::move(provider)),
      tick_clock_(base::DefaultTickClock::GetInstance()),
      delay_enabled_(factory->delay_enabled()),
      weak_factory_(this) {
  defer_conditions_.emplace_back(std::make_unique<InsecureCondition>(
      factory->insecure_delay(), provider_.get()));
  defer_conditions_.emplace_back(std::make_unique<NonIsolatedCondition>(
      factory->non_isolated_delay(), provider_.get()));
}

}  // namespace subresource_filter
