// 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 "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_fetcher.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,
                         net::URLRequestContextGetter* request_context)
    : server_url_(server_url),
      mime_type_(mime_type),
      request_context_(request_context),
      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;
  current_fetch_ =
      net::URLFetcher::Create(server_url_, net::URLFetcher::POST, this);
  data_use_measurement::DataUseUserData::AttachToFetcher(
      current_fetch_.get(), data_use_measurement::DataUseUserData::RAPPOR);
  current_fetch_->SetRequestContext(request_context_.get());
  current_fetch_->SetUploadData(mime_type_, queued_logs_.front());

  // We already drop cookies server-side, but we might as well strip them out
  // client-side as well.
  current_fetch_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
                               net::LOAD_DO_NOT_SEND_COOKIES);
  current_fetch_->Start();
}

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

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

void LogUploader::OnURLFetchComplete(const net::URLFetcher* source) {
  // We're not allowed to re-use the existing |URLFetcher|s, so free them here.
  // Note however that |source| is aliased to the fetcher, so we should be
  // careful not to delete it too early.
  DCHECK_EQ(current_fetch_.get(), source);
  scoped_ptr<net::URLFetcher> fetch(current_fetch_.Pass());

  const net::URLRequestStatus& request_status = source->GetStatus();

  const int response_code = source->GetResponseCode();
  DVLOG(2) << "Upload fetch complete response code: " << response_code;

  if (request_status.status() != net::URLRequestStatus::SUCCESS) {
    UMA_HISTOGRAM_SPARSE_SLOWLY("Rappor.FailedUploadErrorCode",
                                -request_status.error());
    DVLOG(1) << "Rappor server upload failed with error: "
             << request_status.error() << ": "
             << net::ErrorToString(request_status.error());
    DCHECK_EQ(-1, response_code);
  } else {
    // Log a histogram to track response success vs. failure rates.
    UMA_HISTOGRAM_SPARSE_SLOWLY("Rappor.UploadResponseCode", response_code);
  }

  const bool upload_succeeded = response_code == 200;

  // 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
