// Copyright 2019 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 "remoting/signaling/remoting_log_to_server.h"

#include <sstream>

#include "base/bind.h"
#include "base/logging.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "remoting/base/protobuf_http_client.h"
#include "remoting/base/protobuf_http_request.h"
#include "remoting/base/protobuf_http_request_config.h"
#include "remoting/base/protobuf_http_status.h"
#include "remoting/base/service_urls.h"
#include "remoting/proto/remoting/v1/telemetry_messages.pb.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

namespace remoting {

namespace {

const net::BackoffEntry::Policy kBackoffPolicy = {
    // Number of initial errors (in sequence) to ignore before applying
    // exponential back-off rules.
    0,

    // Initial delay for exponential back-off in ms.
    1000,

    // Factor by which the waiting time will be multiplied.
    2,

    // Fuzzing percentage. ex: 10% will spread requests randomly
    // between 90%-100% of the calculated time.
    0.5,

    // Maximum amount of time we are willing to delay our request in ms.
    60000,

    // Time to keep an entry from being discarded even when it
    // has no significant state, -1 to never discard.
    -1,

    // Starts with initial delay.
    false,
};

constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("remoting_log_to_server",
                                        R"(
        semantics {
          sender: "Chrome Remote Desktop"
          description:
            "Sends telemetry logs for Chrome Remote Desktop."
          trigger:
            "These requests are sent periodically when a session is connected, "
            "i.e. CRD host is running and is connected to a client."
          data:
            "Anonymous usage statistics, which includes CRD host version, OS "
            "name, OS version, and CPU architecture (e.g. x86_64)."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting:
            "This request cannot be stopped in settings, but will not be sent "
            "if the user does not use Chrome Remote Desktop."
          policy_exception_justification:
            "Not implemented."
        })");

constexpr char kCreateLogEntryPath[] = "/v1/telemetry:createlogentry";

using CreateLogEntryResponseCallback =
    base::OnceCallback<void(const ProtobufHttpStatus&,
                            std::unique_ptr<apis::v1::CreateLogEntryResponse>)>;

class TelemetryClient {
 public:
  TelemetryClient(
      OAuthTokenGetter* token_getter,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
  ~TelemetryClient();

  void CreateLogEntry(const apis::v1::CreateLogEntryRequest& request,
                      CreateLogEntryResponseCallback callback);

 private:
  ProtobufHttpClient http_client_;
  DISALLOW_COPY_AND_ASSIGN(TelemetryClient);
};

TelemetryClient::TelemetryClient(
    OAuthTokenGetter* token_getter,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
    : http_client_(ServiceUrls::GetInstance()->remoting_server_endpoint(),
                   token_getter,
                   url_loader_factory) {}

TelemetryClient::~TelemetryClient() = default;

void TelemetryClient::CreateLogEntry(
    const apis::v1::CreateLogEntryRequest& request,
    CreateLogEntryResponseCallback callback) {
  auto request_config =
      std::make_unique<ProtobufHttpRequestConfig>(kTrafficAnnotation);
  request_config->path = kCreateLogEntryPath;
  request_config->request_message =
      std::make_unique<apis::v1::CreateLogEntryRequest>(request);
  auto http_request =
      std::make_unique<ProtobufHttpRequest>(std::move(request_config));
  http_request->SetResponseCallback(std::move(callback));
  http_client_.ExecuteRequest(std::move(http_request));
}

}  // namespace

RemotingLogToServer::RemotingLogToServer(
    ServerLogEntry::Mode mode,
    std::unique_ptr<OAuthTokenGetter> token_getter,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
    : mode_(mode),
      token_getter_(std::move(token_getter)),
      backoff_(&kBackoffPolicy),
      create_log_entry_(base::BindRepeating(
          &TelemetryClient::CreateLogEntry,
          std::make_unique<TelemetryClient>(token_getter_.get(),
                                            url_loader_factory))) {}

RemotingLogToServer::~RemotingLogToServer() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

void RemotingLogToServer::Log(const ServerLogEntry& entry) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  apis::v1::CreateLogEntryRequest request;
  *request.mutable_payload()->mutable_entry() = entry.ToGenericLogEntry();
  SendLogRequestWithBackoff(request, kMaxSendLogAttempts);
}

void RemotingLogToServer::SendLogRequest(
    const apis::v1::CreateLogEntryRequest& request,
    int attempts_left) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (VLOG_IS_ON(1)) {
    std::ostringstream log_stream;
    log_stream << "Sending log entry with " << attempts_left
               << " attempts left: \n";
    for (const auto& field : request.payload().entry().field()) {
      log_stream << field.key() << ": " << field.value() << "\n";
    }
    log_stream << "=========================================================";
    VLOG(1) << log_stream.str();
  }
  create_log_entry_.Run(
      request,
      base::BindOnce(&RemotingLogToServer::OnSendLogRequestResult,
                     base::Unretained(this), request, attempts_left - 1));
}

void RemotingLogToServer::SendLogRequestWithBackoff(
    const apis::v1::CreateLogEntryRequest& request,
    int attempts_left) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  auto time_until_release = backoff_.GetTimeUntilRelease();
  VLOG(1) << "Scheduling request in " << time_until_release
          << ", attempts left: " << attempts_left;
  backoff_timer_.Start(
      FROM_HERE, time_until_release,
      base::BindOnce(&RemotingLogToServer::SendLogRequest,
                     base::Unretained(this), request, attempts_left));
}

void RemotingLogToServer::OnSendLogRequestResult(
    const apis::v1::CreateLogEntryRequest& request,
    int attempts_left,
    const ProtobufHttpStatus& status,
    std::unique_ptr<apis::v1::CreateLogEntryResponse> response) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (status.ok()) {
    VLOG(1) << "One log has been successfully sent.";
    backoff_.InformOfRequest(true);
    return;
  }
  LOG(WARNING) << "Failed to send one log."
               << " Error: " << static_cast<int>(status.error_code())
               << " Message: " << status.error_message();
  backoff_.InformOfRequest(false);
  if (attempts_left <= 0) {
    LOG(WARNING) << "Exceeded maximum retry attempts. Dropping it...";
    return;
  }
  SendLogRequestWithBackoff(request, attempts_left);
}

ServerLogEntry::Mode RemotingLogToServer::mode() const {
  return mode_;
}

}  // namespace remoting
