// 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/hash/sha1.h"
#include "base/i18n/time_formatting.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.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/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) {
  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->credentials_mode = network::mojom::CredentialsMode::kOmit;
  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");
  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
