// Copyright 2014 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/rappor/log_uploader.h"

#include <stddef.h>
#include <stdint.h>
#include <utility>

#include "base/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/traffic_annotation/network_traffic_annotation.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"

namespace {

// The delay, in seconds, between uploading when there are queued logs to send.
const int kUnsentLogsIntervalSeconds = 3;

// When uploading metrics to the server fails, we progressively wait longer and
// longer before sending the next log. This backoff process helps reduce load
// on a server that is having issues.
// The following is the multiplier we use to expand that inter-log duration.
const double kBackoffMultiplier = 1.1;

// The maximum backoff multiplier.
const int kMaxBackoffIntervalSeconds = 60 * 60;

// The maximum number of unsent logs we will keep.
// TODO(holte): Limit based on log size instead.
const size_t kMaxQueuedLogs = 10;

enum DiscardReason {
  UPLOAD_SUCCESS,
  UPLOAD_REJECTED,
  QUEUE_OVERFLOW,
  NUM_DISCARD_REASONS
};

void RecordDiscardReason(DiscardReason reason) {
  UMA_HISTOGRAM_ENUMERATION("Rappor.DiscardReason",
                            reason,
                            NUM_DISCARD_REASONS);
}

}  // namespace

namespace rappor {

LogUploader::LogUploader(
    const GURL& server_url,
    const std::string& mime_type,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
    : server_url_(server_url),
      mime_type_(mime_type),
      url_loader_factory_(std::move(url_loader_factory)),
      is_running_(false),
      has_callback_pending_(false),
      upload_interval_(
          base::TimeDelta::FromSeconds(kUnsentLogsIntervalSeconds)) {}

LogUploader::~LogUploader() {}

void LogUploader::Start() {
  is_running_ = true;
  StartScheduledUpload();
}

void LogUploader::Stop() {
  is_running_ = false;
  // Rather than interrupting the current upload, just let it finish/fail and
  // then inhibit any retry attempts.
}

void LogUploader::QueueLog(const std::string& log) {
  queued_logs_.push(log);
  // Don't drop logs yet if an upload is in progress.  They will be dropped
  // when it finishes.
  if (!has_callback_pending_)
    DropExcessLogs();
  StartScheduledUpload();
}

void LogUploader::DropExcessLogs() {
  while (queued_logs_.size() > kMaxQueuedLogs) {
    DVLOG(2) << "Dropping excess log.";
    RecordDiscardReason(QUEUE_OVERFLOW);
    queued_logs_.pop();
  }
}

bool LogUploader::IsUploadScheduled() const {
  return upload_timer_.IsRunning();
}

void LogUploader::ScheduleNextUpload(base::TimeDelta interval) {
  upload_timer_.Start(
      FROM_HERE, interval, this, &LogUploader::StartScheduledUpload);
}

bool LogUploader::CanStartUpload() const {
  return is_running_ &&
         !queued_logs_.empty() &&
         !IsUploadScheduled() &&
         !has_callback_pending_;
}

void LogUploader::StartScheduledUpload() {
  if (!CanStartUpload())
    return;
  DVLOG(2) << "Upload to " << server_url_.spec() << " starting.";
  has_callback_pending_ = true;
  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("rappor_report", R"(
        semantics {
          sender: "RAPPOR"
          description:
            "This service sends RAPPOR anonymous usage statistics to Google."
          trigger:
            "Reports are automatically generated on startup and at intervals "
            "while Chromium is running."
          data: "A protocol buffer with RAPPOR anonymous usage statistics."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting:
            "Users can enable or disable this feature by stopping "
            "'Automatically send usage statistics and crash reports to Google'"
            "in Chromium's settings under Advanced Settings, Privacy. The "
            "feature is enabled by default."
          chrome_policy {
            MetricsReportingEnabled {
              policy_options {mode: MANDATORY}
              MetricsReportingEnabled: false
            }
          }
        })");

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = server_url_;
  // We already drop cookies server-side, but we might as well strip them out
  // client-side as well.
  resource_request->allow_credentials = false;
  resource_request->method = "POST";
  simple_url_loader_ = network::SimpleURLLoader::Create(
      std::move(resource_request), traffic_annotation);
  simple_url_loader_->AttachStringForUpload(queued_logs_.front(), mime_type_);
  // TODO re-add data use measurement once SimpleURLLoader supports it.
  // ID=data_use_measurement::DataUseUserData::RAPPOR
  simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      url_loader_factory_.get(),
      base::BindOnce(&LogUploader::OnSimpleLoaderComplete,
                     base::Unretained(this)));
}

// static
base::TimeDelta LogUploader::BackOffUploadInterval(base::TimeDelta interval) {
  DCHECK_GT(kBackoffMultiplier, 1.0);
  interval = base::TimeDelta::FromMicroseconds(
      static_cast<int64_t>(kBackoffMultiplier * interval.InMicroseconds()));

  base::TimeDelta max_interval =
      base::TimeDelta::FromSeconds(kMaxBackoffIntervalSeconds);
  return interval > max_interval ? max_interval : interval;
}

void LogUploader::OnSimpleLoaderComplete(
    std::unique_ptr<std::string> response_body) {
  int response_code = -1;
  if (simple_url_loader_->ResponseInfo() &&
      simple_url_loader_->ResponseInfo()->headers) {
    response_code =
        simple_url_loader_->ResponseInfo()->headers->response_code();
  }
  DVLOG(2) << "Upload fetch complete response code: " << response_code;

  int net_error = simple_url_loader_->NetError();
  if (net_error != net::OK && (response_code == -1 || response_code == 200)) {
    base::UmaHistogramSparse("Rappor.FailedUploadErrorCode", -net_error);
    DVLOG(1) << "Rappor server upload failed with error: " << net_error << ": "
             << net::ErrorToString(net_error);
  } else {
    // Log a histogram to track response success vs. failure rates.
    base::UmaHistogramSparse("Rappor.UploadResponseCode", response_code);
  }

  const bool upload_succeeded = !!response_body;

  // Determine whether this log should be retransmitted.
  DiscardReason reason = NUM_DISCARD_REASONS;
  if (upload_succeeded) {
    reason = UPLOAD_SUCCESS;
  } else if (response_code == 400) {
    reason = UPLOAD_REJECTED;
  }

  if (reason != NUM_DISCARD_REASONS) {
    DVLOG(2) << "Log discarded.";
    RecordDiscardReason(reason);
    queued_logs_.pop();
  }

  DropExcessLogs();

  // Error 400 indicates a problem with the log, not with the server, so
  // don't consider that a sign that the server is in trouble.
  const bool server_is_healthy = upload_succeeded || response_code == 400;
  OnUploadFinished(server_is_healthy);
}

void LogUploader::OnUploadFinished(bool server_is_healthy) {
  DCHECK(has_callback_pending_);
  has_callback_pending_ = false;
  // If the server is having issues, back off. Otherwise, reset to default.
  if (!server_is_healthy)
    upload_interval_ = BackOffUploadInterval(upload_interval_);
  else
    upload_interval_ = base::TimeDelta::FromSeconds(kUnsentLogsIntervalSeconds);

  if (CanStartUpload())
    ScheduleNextUpload(upload_interval_);
}

}  // namespace rappor
