// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Library functions related to the Financial Server ping.

#include "rlz/lib/financial_ping.h"

#include <stdint.h>

#include <memory>

#include "base/atomicops.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "rlz/lib/assert.h"
#include "rlz/lib/lib_values.h"
#include "rlz/lib/machine_id.h"
#include "rlz/lib/rlz_lib.h"
#include "rlz/lib/rlz_value_store.h"
#include "rlz/lib/string_utils.h"
#include "rlz/lib/time_util.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/url_response_head.mojom.h"

#if !BUILDFLAG(IS_WIN)
#include "base/time/time.h"
#endif

#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "url/gurl.h"

namespace rlz_lib {

using base::subtle::AtomicWord;

bool FinancialPing::FormRequest(Product product,
    const AccessPoint* access_points, const char* product_signature,
    const char* product_brand, const char* product_id,
    const char* product_lang, bool exclude_machine_id,
    std::string* request) {
  if (!request) {
    ASSERT_STRING("FinancialPing::FormRequest: request is NULL");
    return false;
  }

  request->clear();

  ScopedRlzValueStoreLock lock;
  RlzValueStore* store = lock.GetStore();
  if (!store || !store->HasAccess(RlzValueStore::kReadAccess))
    return false;

  if (!access_points) {
    ASSERT_STRING("FinancialPing::FormRequest: access_points is NULL");
    return false;
  }

  if (!product_signature) {
    ASSERT_STRING("FinancialPing::FormRequest: product_signature is NULL");
    return false;
  }

  if (!SupplementaryBranding::GetBrand().empty()) {
    if (SupplementaryBranding::GetBrand() != product_brand) {
      ASSERT_STRING("FinancialPing::FormRequest: supplementary branding bad");
      return false;
    }
  }

  base::StringAppendF(request, "%s?", kFinancialPingPath);

  // Add the signature, brand, product id and language.
  base::StringAppendF(request, "%s=%s", kProductSignatureCgiVariable,
                      product_signature);
  if (product_brand)
    base::StringAppendF(request, "&%s=%s", kProductBrandCgiVariable,
                        product_brand);

  if (product_id)
    base::StringAppendF(request, "&%s=%s", kProductIdCgiVariable, product_id);

  if (product_lang)
    base::StringAppendF(request, "&%s=%s", kProductLanguageCgiVariable,
                        product_lang);

  // Add the product events.
  char cgi[kMaxCgiLength + 1];
  cgi[0] = 0;
  bool has_events = GetProductEventsAsCgi(product, cgi, std::size(cgi));
  if (has_events)
    base::StringAppendF(request, "&%s", cgi);

  // If we don't have any events, we should ping all the AP's on the system
  // that we know about and have a current RLZ value, even if they are not
  // used by this product.
  AccessPoint all_points[LAST_ACCESS_POINT];
  if (!has_events) {
    char rlz[kMaxRlzLength + 1];
    int idx = 0;
    for (int ap = NO_ACCESS_POINT + 1; ap < LAST_ACCESS_POINT; ap++) {
      rlz[0] = 0;
      AccessPoint point = static_cast<AccessPoint>(ap);
      if (GetAccessPointRlz(point, rlz, std::size(rlz)) && rlz[0] != '\0')
        all_points[idx++] = point;
    }
    all_points[idx] = NO_ACCESS_POINT;
  }

  // Add the RLZ's and the DCC if needed. This is the same as get PingParams.
  // This will also include the RLZ Exchange Protocol CGI Argument.
  cgi[0] = 0;
  if (GetPingParams(product, has_events ? access_points : all_points, cgi,
                    std::size(cgi)))
    base::StringAppendF(request, "&%s", cgi);

  if (has_events && !exclude_machine_id) {
    std::string machine_id;
    if (GetMachineId(&machine_id)) {
      base::StringAppendF(request, "&%s=%s", kMachineIdCgiVariable,
                          machine_id.c_str());
    }
  }

  return true;
}

namespace {

// A waitable event used to detect when either:
//
//   1/ the RLZ ping request completes
//   2/ the RLZ ping request times out
//   3/ browser shutdown begins
class RefCountedWaitableEvent
    : public base::RefCountedThreadSafe<RefCountedWaitableEvent> {
 public:
  RefCountedWaitableEvent()
      : event_(base::WaitableEvent::ResetPolicy::MANUAL,
               base::WaitableEvent::InitialState::NOT_SIGNALED) {}

  void SignalShutdown() { event_.Signal(); }

  void SignalFetchComplete(int response_code, std::string response) {
    base::AutoLock autolock(lock_);
    response_code_ = response_code;
    response_ = std::move(response);
    event_.Signal();
  }

  bool TimedWait(base::TimeDelta timeout) { return event_.TimedWait(timeout); }

  int GetResponseCode() {
    base::AutoLock autolock(lock_);
    return response_code_;
  }

  std::string TakeResponse() {
    base::AutoLock autolock(lock_);
    std::string temp = std::move(response_);
    response_.clear();
    return temp;
  }

 private:
  ~RefCountedWaitableEvent() = default;
  friend class base::RefCountedThreadSafe<RefCountedWaitableEvent>;

  base::WaitableEvent event_;
  base::Lock lock_;
  std::string response_;
  int response_code_ = -1;
};

// The URL load complete callback signals an instance of
// RefCountedWaitableEvent when the load completes.
void OnURLLoadComplete(std::unique_ptr<network::SimpleURLLoader> url_loader,
                       scoped_refptr<RefCountedWaitableEvent> event,
                       std::unique_ptr<std::string> response_body) {
  int response_code = -1;
  if (url_loader->ResponseInfo() && url_loader->ResponseInfo()->headers) {
    response_code = url_loader->ResponseInfo()->headers->response_code();
  }

  std::string response;
  if (response_body) {
    response = std::move(*response_body);
  }

  event->SignalFetchComplete(response_code, std::move(response));
}

bool send_financial_ping_interrupted_for_test = false;

}  // namespace

// The signal for the current ping request. It can be used to cancel the request
// in case of a shutdown.
scoped_refptr<RefCountedWaitableEvent>& GetPingResultEvent() {
  static base::NoDestructor<scoped_refptr<RefCountedWaitableEvent>>
      g_pingResultEvent;
  return *g_pingResultEvent;
}

// The pointer to URLRequestContextGetter used by FinancialPing::PingServer().
// It is atomic pointer because it can be accessed and modified by multiple
// threads.
AtomicWord g_URLLoaderFactory;

bool FinancialPing::SetURLLoaderFactory(
    network::mojom::URLLoaderFactory* factory) {
  base::subtle::Release_Store(&g_URLLoaderFactory,
                              reinterpret_cast<AtomicWord>(factory));
  scoped_refptr<RefCountedWaitableEvent> event = GetPingResultEvent();
  if (!factory && event) {
    send_financial_ping_interrupted_for_test = true;
    event->SignalShutdown();
  }
  return true;
}

void PingRlzServer(std::string url,
                   scoped_refptr<RefCountedWaitableEvent> event) {
  // Copy the pointer to stack because g_URLLoaderFactory may be set to NULL
  // in different thread. The instance is guaranteed to exist while
  // the method is running.
  network::mojom::URLLoaderFactory* url_loader_factory =
      reinterpret_cast<network::mojom::URLLoaderFactory*>(
          base::subtle::Acquire_Load(&g_URLLoaderFactory));

  // Browser shutdown will cause the factory to be reset to NULL.
  // ShutdownCheck will catch this.
  if (!url_loader_factory) {
    event->SignalFetchComplete(-1, "");
    return;
  }

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("rlz_ping", R"(
        semantics {
          sender: "RLZ Ping"
          description:
            "Used for measuring the effectiveness of a promotion. See the "
            "Chrome Privacy Whitepaper for complete details."
          trigger:
            "1- At Chromium first run.\n"
            "2- When Chromium is re-activated by a new promotion.\n"
            "3- Once a week thereafter as long as Chromium is used.\n"
          data:
            "1- Non-unique cohort tag of when Chromium was installed.\n"
            "2- Unique machine id on desktop platforms.\n"
            "3- Whether Google is the default omnibox search.\n"
            "4- Whether google.com is the default home page."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting: "This feature cannot be disabled in settings."
          policy_exception_justification: "Not implemented."
        })");
  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(url);
  resource_request->load_flags = net::LOAD_DISABLE_CACHE;
  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;

  auto url_loader = network::SimpleURLLoader::Create(
      std::move(resource_request), traffic_annotation);

  constexpr int kMaxNetworkRetries = 3;
  url_loader->SetRetryOptions(
      kMaxNetworkRetries,
      network::SimpleURLLoader::RetryMode::RETRY_ON_5XX |
          network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE |
          network::SimpleURLLoader::RETRY_ON_NAME_NOT_RESOLVED);

  // Pass ownership of the loader to the bound function. Otherwise the load will
  // be canceled when the SimpleURLLoader object is destroyed.
  auto* url_loader_ptr = url_loader.get();
  url_loader_ptr->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      url_loader_factory,
      base::BindOnce(&OnURLLoadComplete, std::move(url_loader),
                     std::move(event)));
}

FinancialPing::PingResponse FinancialPing::PingServer(const char* request,
                                                      std::string* response) {
  if (!response)
    return PING_FAILURE;

  response->clear();

  std::string url =
      base::StringPrintf("https://%s%s", kFinancialServer, request);

  // Use a waitable event to cause this function to block, to match the
  // wininet implementation.
  auto event = base::MakeRefCounted<RefCountedWaitableEvent>();
  scoped_refptr<RefCountedWaitableEvent>& event_ref = GetPingResultEvent();
  event_ref = event;

  // PingRlzServer must be run in a separate sequence so that the TimedWait()
  // call below does not block the URL fetch response from being handled by
  // the URL delegate.
  scoped_refptr<base::SequencedTaskRunner> background_runner(
      base::ThreadPool::CreateSequencedTaskRunner(
          {base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
           base::TaskPriority::BEST_EFFORT}));
  background_runner->PostTask(FROM_HERE,
                              base::BindOnce(&PingRlzServer, url, event));

  bool is_signaled;
  {
    base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
    is_signaled = event->TimedWait(base::Minutes(5));
  }

  event_ref.reset();
  if (!is_signaled)
    return PING_FAILURE;

  if (event->GetResponseCode() == -1) {
    send_financial_ping_interrupted_for_test = true;
    return PING_SHUTDOWN;
  } else if (event->GetResponseCode() != 200) {
    return PING_FAILURE;
  }

  *response = event->TakeResponse();
  return PING_SUCCESSFUL;
}

bool FinancialPing::IsPingTime(Product product, bool no_delay) {
  ScopedRlzValueStoreLock lock;
  RlzValueStore* store = lock.GetStore();
  if (!store || !store->HasAccess(RlzValueStore::kReadAccess))
    return false;

  int64_t last_ping = 0;
  if (!store->ReadPingTime(product, &last_ping))
    return true;

  uint64_t now = GetSystemTimeAsInt64();
  int64_t interval = now - last_ping;

  // If interval is negative, clock was probably reset. So ping.
  if (interval < 0)
    return true;

  // Check if this product has any unreported events.
  char cgi[kMaxCgiLength + 1];
  cgi[0] = 0;
  bool has_events = GetProductEventsAsCgi(product, cgi, std::size(cgi));
  if (no_delay && has_events)
    return true;

  return interval >= (has_events ? kEventsPingInterval : kNoEventsPingInterval);
}


bool FinancialPing::UpdateLastPingTime(Product product) {
  ScopedRlzValueStoreLock lock;
  RlzValueStore* store = lock.GetStore();
  if (!store || !store->HasAccess(RlzValueStore::kWriteAccess))
    return false;

  uint64_t now = GetSystemTimeAsInt64();
  return store->WritePingTime(product, now);
}


bool FinancialPing::ClearLastPingTime(Product product) {
  ScopedRlzValueStoreLock lock;
  RlzValueStore* store = lock.GetStore();
  if (!store || !store->HasAccess(RlzValueStore::kWriteAccess))
    return false;
  return store->ClearPingTime(product);
}

namespace test {

void ResetSendFinancialPingInterrupted() {
  send_financial_ping_interrupted_for_test = false;
}

bool WasSendFinancialPingInterrupted() {
  return send_financial_ping_interrupted_for_test;
}

}  // namespace test

}  // namespace rlz_lib
