// Copyright 2020 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/base/protobuf_http_client.h"

#include "base/strings/stringprintf.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "remoting/base/oauth_token_getter.h"
#include "remoting/base/protobuf_http_request_base.h"
#include "remoting/base/protobuf_http_request_config.h"
#include "remoting/base/protobuf_http_status.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 "third_party/protobuf/src/google/protobuf/message_lite.h"
#include "url/gurl.h"

namespace {

constexpr char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s";
constexpr char kApiKeyHeaderFormat[] = "x-goog-api-key: %s";

}  // namespace

namespace remoting {

ProtobufHttpClient::ProtobufHttpClient(
    const std::string& server_endpoint,
    OAuthTokenGetter* token_getter,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
    : server_endpoint_(server_endpoint),
      token_getter_(token_getter),
      url_loader_factory_(url_loader_factory) {}

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

void ProtobufHttpClient::ExecuteRequest(
    std::unique_ptr<ProtobufHttpRequestBase> request) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!request->config().authenticated) {
    DoExecuteRequest(std::move(request), OAuthTokenGetter::Status::SUCCESS, {},
                     {});
    return;
  }

  DCHECK(token_getter_);
  token_getter_->CallWithToken(
      base::BindOnce(&ProtobufHttpClient::DoExecuteRequest,
                     weak_factory_.GetWeakPtr(), std::move(request)));
}

void ProtobufHttpClient::CancelPendingRequests() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  weak_factory_.InvalidateWeakPtrs();
  pending_requests_.clear();
}

bool ProtobufHttpClient::HasPendingRequests() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return !pending_requests_.empty();
}

void ProtobufHttpClient::DoExecuteRequest(
    std::unique_ptr<ProtobufHttpRequestBase> request,
    OAuthTokenGetter::Status status,
    const std::string& user_email,
    const std::string& access_token) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (status != OAuthTokenGetter::Status::SUCCESS) {
    std::string error_message =
        base::StringPrintf("Failed to fetch access token. Status: %d", status);
    LOG(ERROR) << error_message;
    ProtobufHttpStatus::Code code;
    switch (status) {
      case OAuthTokenGetter::Status::AUTH_ERROR:
        code = ProtobufHttpStatus::Code::UNAUTHENTICATED;
        break;
      case OAuthTokenGetter::Status::NETWORK_ERROR:
        code = ProtobufHttpStatus::Code::UNAVAILABLE;
        break;
      default:
        NOTREACHED() << "Unknown OAuthTokenGetter Status: " << status;
        code = ProtobufHttpStatus::Code::UNKNOWN;
    }
    request->OnAuthFailed(ProtobufHttpStatus(code, error_message));
    return;
  }

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url =
      GURL("https://" + server_endpoint_ + request->config().path);
  resource_request->load_flags =
      net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE;
  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
  resource_request->method = net::HttpRequestHeaders::kPostMethod;

  if (status == OAuthTokenGetter::Status::SUCCESS && !access_token.empty()) {
    resource_request->headers.AddHeaderFromString(
        base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str()));
  } else {
    VLOG(1) << "Attempting to execute request without access token";
  }

  if (!request->config().api_key.empty()) {
    resource_request->headers.AddHeaderFromString(base::StringPrintf(
        kApiKeyHeaderFormat, request->config().api_key.c_str()));
  }

  std::unique_ptr<network::SimpleURLLoader> send_url_loader =
      network::SimpleURLLoader::Create(std::move(resource_request),
                                       request->config().traffic_annotation);
  base::TimeDelta timeout_duration = request->GetRequestTimeoutDuration();
  if (!timeout_duration.is_zero()) {
    send_url_loader->SetTimeoutDuration(request->GetRequestTimeoutDuration());
  }
  send_url_loader->AttachStringForUpload(
      request->config().request_message->SerializeAsString(),
      "application/x-protobuf");
  send_url_loader->SetAllowHttpErrorResults(true);
  auto* unowned_request = request.get();
  base::OnceClosure invalidator = base::BindOnce(
      &ProtobufHttpClient::CancelRequest, weak_factory_.GetWeakPtr(),
      pending_requests_.insert(pending_requests_.end(), std::move(request)));
  unowned_request->StartRequest(url_loader_factory_.get(),
                                std::move(send_url_loader),
                                std::move(invalidator));
}

void ProtobufHttpClient::CancelRequest(
    const PendingRequestListIterator& request_iterator) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  pending_requests_.erase(request_iterator);
}

}  // namespace remoting
