// 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/invalidation/impl/gcm_network_channel.h"

#include <utility>

#include "base/base64url.h"
#include "base/bind.h"
#include "base/i18n/time_formatting.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
#include "base/sha1.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/invalidation/impl/gcm_network_channel_delegate.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.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"

#if !defined(OS_ANDROID)
// channel_common.proto defines ANDROID constant that conflicts with Android
// build. At the same time TiclInvalidationService is not used on Android so it
// is safe to exclude these protos from Android build.
#include "google/cacheinvalidation/android_channel.pb.h"
#include "google/cacheinvalidation/channel_common.pb.h"
#include "google/cacheinvalidation/types.pb.h"
#endif

namespace syncer {

namespace {

const char kCacheInvalidationEndpointUrl[] =
    "https://clients4.google.com/invalidation/android/request/";
const char kCacheInvalidationPackageName[] = "com.google.chrome.invalidations";

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

  // Initial delay for exponential back-off in ms.
  2000, // 2 seconds.

  // 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.2, // 20%.

  // Maximum amount of time we are willing to delay our request in ms.
  1000 * 3600 * 4, // 4 hours.

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

  // Don't use initial delay unless the last request was an error.
  false,
};

// Incoming message status values for UMA_HISTOGRAM.
enum IncomingMessageStatus {
  INCOMING_MESSAGE_SUCCESS,
  MESSAGE_EMPTY,     // GCM message's content is missing or empty.
  INVALID_ENCODING,  // Base64Decode failed.
  INVALID_PROTO,     // Parsing protobuf failed.

  // This enum is used in UMA_HISTOGRAM_ENUMERATION. Insert new values above
  // this line.
  INCOMING_MESSAGE_STATUS_COUNT
};

// Outgoing message status values for UMA_HISTOGRAM.
enum OutgoingMessageStatus {
  OUTGOING_MESSAGE_SUCCESS,
  MESSAGE_DISCARDED,     // New message started before old one was sent.
  ACCESS_TOKEN_FAILURE,  // Requeting access token failed.
  POST_FAILURE,          // HTTP Post failed.

  // This enum is used in UMA_HISTOGRAM_ENUMERATION. Insert new values above
  // this line.
  OUTGOING_MESSAGE_STATUS_COUNT
};

const char kIncomingMessageStatusHistogram[] =
    "GCMInvalidations.IncomingMessageStatus";
const char kOutgoingMessageStatusHistogram[] =
    "GCMInvalidations.OutgoingMessageStatus";

void RecordIncomingMessageStatus(IncomingMessageStatus status) {
  UMA_HISTOGRAM_ENUMERATION(kIncomingMessageStatusHistogram,
                            status,
                            INCOMING_MESSAGE_STATUS_COUNT);
}

void RecordOutgoingMessageStatus(OutgoingMessageStatus status) {
  UMA_HISTOGRAM_ENUMERATION(kOutgoingMessageStatusHistogram,
                            status,
                            OUTGOING_MESSAGE_STATUS_COUNT);
}

}  // namespace

GCMNetworkChannel::GCMNetworkChannel(
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    network::NetworkConnectionTracker* network_connection_tracker,
    std::unique_ptr<GCMNetworkChannelDelegate> delegate)
    : url_loader_factory_(std::move(url_loader_factory)),
      network_connection_tracker_(network_connection_tracker),
      delegate_(std::move(delegate)),
      register_backoff_entry_(new net::BackoffEntry(&kRegisterBackoffPolicy)),
      gcm_channel_online_(false),
      http_channel_online_(false),
      diagnostic_info_(this),
      weak_factory_(this) {
  network_connection_tracker_->AddNetworkConnectionObserver(this);
  delegate_->Initialize(
      base::Bind(&GCMNetworkChannel::OnConnectionStateChanged,
                 weak_factory_.GetWeakPtr()),
      base::Bind(&GCMNetworkChannel::OnStoreReset, weak_factory_.GetWeakPtr()));
  Register();
}

GCMNetworkChannel::~GCMNetworkChannel() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  network_connection_tracker_->RemoveNetworkConnectionObserver(this);
}

void GCMNetworkChannel::Register() {
  delegate_->Register(base::Bind(&GCMNetworkChannel::OnRegisterComplete,
                                 weak_factory_.GetWeakPtr()));
}

void GCMNetworkChannel::OnRegisterComplete(
    const std::string& registration_id,
    gcm::GCMClient::Result result) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (result == gcm::GCMClient::SUCCESS) {
    DCHECK(!registration_id.empty());
    DVLOG(2) << "Got registration_id";
    register_backoff_entry_->Reset();
    registration_id_ = registration_id;
    if (!cached_message_.empty())
      RequestAccessToken();
  } else {
    DVLOG(2) << "Register failed: " << result;
    // Retry in case of transient error.
    switch (result) {
      case gcm::GCMClient::NETWORK_ERROR:
      case gcm::GCMClient::SERVER_ERROR:
      case gcm::GCMClient::TTL_EXCEEDED:
      case gcm::GCMClient::UNKNOWN_ERROR: {
        register_backoff_entry_->InformOfRequest(false);
        base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
            FROM_HERE,
            base::BindOnce(&GCMNetworkChannel::Register,
                           weak_factory_.GetWeakPtr()),
            register_backoff_entry_->GetTimeUntilRelease());
        break;
      }
      default:
        break;
    }
  }
  diagnostic_info_.registration_id_ = registration_id_;
  diagnostic_info_.registration_result_ = result;
}

void GCMNetworkChannel::SendMessage(const std::string& message) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!message.empty());
  DVLOG(2) << "SendMessage";
  diagnostic_info_.sent_messages_count_++;
  if (!cached_message_.empty()) {
    RecordOutgoingMessageStatus(MESSAGE_DISCARDED);
  }
  cached_message_ = message;

  if (!registration_id_.empty()) {
    RequestAccessToken();
  }
}

void GCMNetworkChannel::RequestAccessToken() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  delegate_->RequestToken(base::Bind(&GCMNetworkChannel::OnGetTokenComplete,
                                     weak_factory_.GetWeakPtr()));
}

void GCMNetworkChannel::OnGetTokenComplete(
    const GoogleServiceAuthError& error,
    const std::string& token) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (cached_message_.empty() || registration_id_.empty()) {
    // Nothing to do.
    return;
  }

  if (error.state() != GoogleServiceAuthError::NONE) {
    // Requesting access token failed. Persistent errors will be reported by
    // token service. Just drop this request, cacheinvalidations will retry
    // sending message and at that time we'll retry requesting access token.
    DVLOG(1) << "RequestAccessToken failed: " << error.ToString();
    RecordOutgoingMessageStatus(ACCESS_TOKEN_FAILURE);
    // Message won't get sent. Notify that http channel doesn't work.
    UpdateHttpChannelState(false);
    cached_message_.clear();
    return;
  }
  DCHECK(!token.empty());
  // Save access token in case POST fails and we need to invalidate it.
  access_token_ = token;

  DVLOG(2) << "Got access token, sending message";
  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("invalidation_service", R"(
        semantics {
          sender: "Invalidation service"
          description:
            "Chromium uses cacheinvalidation library to receive push "
            "notifications from the server about sync items (bookmarks, "
            "passwords, preferences, etc.) modified on other clients. It uses "
            "GCMClient to receive incoming messages. This request is used for "
            "client-to-server communications."
          trigger:
            "The first message is sent to register client with the server on "
            "Chromium startup. It is then sent periodically to confirm that "
            "the client is still online. After receiving notification about "
            "server changes, the client sends this request to acknowledge that "
            "the notification is processed."
          data:
            "Different in each use case:\n"
            "- Initial registration: Doesn't contain user data.\n"
            "- Updating the set of subscriptions: Contains server generated "
            "client_token and ObjectIds identifying subscriptions. ObjectId "
            "is not unique to user.\n"
            "- Invalidation acknowledgement: Contains client_token, ObjectId "
            "and server version for corresponding subscription. Version is not "
            "related to sync data, it is an internal concept of invalidations "
            "protocol."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting: "This feature cannot be disabled."
          policy_exception_justification:
            "Not implemented. Disabling InvalidationService might break "
            "features that depend on it. It makes sense to control top level "
            "features that use InvalidationService."
        })");

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = BuildUrl(registration_id_);
  resource_request->load_flags =
      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
  resource_request->method = "POST";
  resource_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
                                      "Bearer " + access_token_);
  if (!echo_token_.empty()) {
    resource_request->headers.SetHeader("echo-token", echo_token_);
  }
  simple_url_loader_ = network::SimpleURLLoader::Create(
      std::move(resource_request), traffic_annotation);
  simple_url_loader_->AttachStringForUpload(cached_message_,
                                            "application/x-protobuffer");
  // TODO(https://crbug.com/808498): Re-add data use measurement once
  // SimpleURLLoader supports it.
  // ID=data_use_measurement::DataUseUserData::INVALIDATION
  simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      url_loader_factory_.get(),
      base::BindOnce(&GCMNetworkChannel::OnSimpleLoaderComplete,
                     base::Unretained(this)));
  // Clear message to prevent accidentally resending it in the future.
  cached_message_.clear();
}

void GCMNetworkChannel::OnSimpleLoaderComplete(
    std::unique_ptr<std::string> response_body) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  int net_error = simple_url_loader_->NetError();
  bool is_success = (net_error == net::OK);
  int response_code = -1;
  if (simple_url_loader_->ResponseInfo() &&
      simple_url_loader_->ResponseInfo()->headers) {
    response_code =
        simple_url_loader_->ResponseInfo()->headers->response_code();
  }
  simple_url_loader_.reset();
  diagnostic_info_.last_post_response_code_ =
      (response_code / 100 != 2 || is_success) ? response_code : net_error;

  if (response_code == net::HTTP_UNAUTHORIZED) {
    DVLOG(1) << "SimpleURLLoader failure: HTTP_UNAUTHORIZED";
    delegate_->InvalidateToken(access_token_);
  }

  if (!response_body) {
    DVLOG(1) << "SimpleURLLoader failure";
    RecordOutgoingMessageStatus(POST_FAILURE);
    // POST failed. Notify that http channel doesn't work.
    UpdateHttpChannelState(false);
    return;
  }

  RecordOutgoingMessageStatus(OUTGOING_MESSAGE_SUCCESS);
  // Successfully sent message. Http channel works.
  UpdateHttpChannelState(true);
  DVLOG(2) << "SimpleURLLoader success";
}

void GCMNetworkChannel::OnIncomingMessage(const std::string& message,
                                          const std::string& echo_token) {
#if !defined(OS_ANDROID)
  if (!echo_token.empty())
    echo_token_ = echo_token;
  diagnostic_info_.last_message_empty_echo_token_ = echo_token.empty();
  diagnostic_info_.last_message_received_time_ = base::Time::Now();

  if (message.empty()) {
    RecordIncomingMessageStatus(MESSAGE_EMPTY);
    return;
  }
  std::string data;
  if (!base::Base64UrlDecode(
          message, base::Base64UrlDecodePolicy::IGNORE_PADDING, &data)) {
    RecordIncomingMessageStatus(INVALID_ENCODING);
    return;
  }
  ipc::invalidation::AddressedAndroidMessage android_message;
  if (!android_message.ParseFromString(data) ||
      !android_message.has_message()) {
    RecordIncomingMessageStatus(INVALID_PROTO);
    return;
  }
  DVLOG(2) << "Deliver incoming message";
  RecordIncomingMessageStatus(INCOMING_MESSAGE_SUCCESS);
  UpdateGcmChannelState(true);
  DeliverIncomingMessage(android_message.message());
#else
  // This code shouldn't be invoked on Android.
  NOTREACHED();
#endif
}

void GCMNetworkChannel::OnConnectionStateChanged(bool online) {
  UpdateGcmChannelState(online);
}

void GCMNetworkChannel::OnStoreReset() {
  // TODO(crbug.com/661660): Tell server the registration ID is no longer valid.
  registration_id_.clear();
}

void GCMNetworkChannel::OnConnectionChanged(
    network::mojom::ConnectionType connection_type) {
  // Network connection is restored. Let's notify cacheinvalidations so it has
  // chance to retry.
  NotifyNetworkStatusChange(connection_type !=
                            network::mojom::ConnectionType::CONNECTION_NONE);
}

void GCMNetworkChannel::UpdateGcmChannelState(bool online) {
  if (gcm_channel_online_ == online)
    return;
  gcm_channel_online_ = online;
  InvalidatorState channel_state = TRANSIENT_INVALIDATION_ERROR;
  if (gcm_channel_online_ && http_channel_online_)
    channel_state = INVALIDATIONS_ENABLED;
  NotifyChannelStateChange(channel_state);
}

void GCMNetworkChannel::UpdateHttpChannelState(bool online) {
  if (http_channel_online_ == online)
    return;
  http_channel_online_ = online;
  InvalidatorState channel_state = TRANSIENT_INVALIDATION_ERROR;
  if (gcm_channel_online_ && http_channel_online_)
    channel_state = INVALIDATIONS_ENABLED;
  NotifyChannelStateChange(channel_state);
}

GURL GCMNetworkChannel::BuildUrl(const std::string& registration_id) {
  DCHECK(!registration_id.empty());

#if !defined(OS_ANDROID)
  ipc::invalidation::EndpointId endpoint_id;
  endpoint_id.set_c2dm_registration_id(registration_id);
  endpoint_id.set_client_key(std::string());
  endpoint_id.set_package_name(kCacheInvalidationPackageName);
  endpoint_id.mutable_channel_version()->set_major_version(
      ipc::invalidation::INITIAL);
  std::string endpoint_id_buffer;
  endpoint_id.SerializeToString(&endpoint_id_buffer);

  ipc::invalidation::NetworkEndpointId network_endpoint_id;
  network_endpoint_id.set_network_address(
      ipc::invalidation::NetworkEndpointId_NetworkAddress_ANDROID);
  network_endpoint_id.set_client_address(endpoint_id_buffer);
  std::string network_endpoint_id_buffer;
  network_endpoint_id.SerializeToString(&network_endpoint_id_buffer);

  std::string base64URLPiece;
  base::Base64UrlEncode(
      network_endpoint_id_buffer, base::Base64UrlEncodePolicy::OMIT_PADDING,
      &base64URLPiece);

  std::string url(kCacheInvalidationEndpointUrl);
  url += base64URLPiece;
  return GURL(url);
#else
  // This code shouldn't be invoked on Android.
  NOTREACHED();
  return GURL();
#endif
}

void GCMNetworkChannel::SetMessageReceiver(
    invalidation::MessageCallback* incoming_receiver) {
  delegate_->SetMessageReceiver(base::Bind(
      &GCMNetworkChannel::OnIncomingMessage, weak_factory_.GetWeakPtr()));
  SyncNetworkChannel::SetMessageReceiver(incoming_receiver);
}

void GCMNetworkChannel::RequestDetailedStatus(
    base::Callback<void(const base::DictionaryValue&)> callback) {
  callback.Run(*diagnostic_info_.CollectDebugData());
}

void GCMNetworkChannel::UpdateCredentials(const std::string& email,
                                          const std::string& token) {
  // Do nothing. We get access token by requesting it for every message.
}

int GCMNetworkChannel::GetInvalidationClientType() {
#if defined(OS_IOS)
  return ipc::invalidation::ClientType::CHROME_SYNC_GCM_IOS;
#else
  return ipc::invalidation::ClientType::CHROME_SYNC_GCM_DESKTOP;
#endif
}

void GCMNetworkChannel::ResetRegisterBackoffEntryForTest(
    const net::BackoffEntry::Policy* policy) {
  register_backoff_entry_.reset(new net::BackoffEntry(policy));
}

GCMNetworkChannelDiagnostic::GCMNetworkChannelDiagnostic(
    GCMNetworkChannel* parent)
    : parent_(parent),
      last_message_empty_echo_token_(false),
      last_post_response_code_(0),
      registration_result_(gcm::GCMClient::UNKNOWN_ERROR),
      sent_messages_count_(0) {}

std::unique_ptr<base::DictionaryValue>
GCMNetworkChannelDiagnostic::CollectDebugData() const {
  std::unique_ptr<base::DictionaryValue> status(new base::DictionaryValue);
  status->SetString("GCMNetworkChannel.Channel", "GCM");
  std::string reg_id_hash = base::SHA1HashString(registration_id_);
  status->SetString("GCMNetworkChannel.HashedRegistrationID",
                    base::HexEncode(reg_id_hash.c_str(), reg_id_hash.size()));
  status->SetString("GCMNetworkChannel.RegistrationResult",
                    GCMClientResultToString(registration_result_));
  status->SetBoolean("GCMNetworkChannel.HadLastMessageEmptyEchoToken",
                     last_message_empty_echo_token_);
  status->SetString(
      "GCMNetworkChannel.LastMessageReceivedTime",
      base::TimeFormatShortDateAndTime(last_message_received_time_));
  status->SetInteger("GCMNetworkChannel.LastPostResponseCode",
                     last_post_response_code_);
  status->SetInteger("GCMNetworkChannel.SentMessages", sent_messages_count_);
  status->SetInteger("GCMNetworkChannel.ReceivedMessages",
                     parent_->GetReceivedMessagesCount());
  return status;
}

std::string GCMNetworkChannelDiagnostic::GCMClientResultToString(
    const gcm::GCMClient::Result result) const {
#define ENUM_CASE(x) case x: return #x; break;
  switch (result) {
    ENUM_CASE(gcm::GCMClient::SUCCESS);
    ENUM_CASE(gcm::GCMClient::NETWORK_ERROR);
    ENUM_CASE(gcm::GCMClient::SERVER_ERROR);
    ENUM_CASE(gcm::GCMClient::TTL_EXCEEDED);
    ENUM_CASE(gcm::GCMClient::UNKNOWN_ERROR);
    ENUM_CASE(gcm::GCMClient::INVALID_PARAMETER);
    ENUM_CASE(gcm::GCMClient::ASYNC_OPERATION_PENDING);
    ENUM_CASE(gcm::GCMClient::GCM_DISABLED);
  }
  NOTREACHED();
  return "";
}

}  // namespace syncer
