// 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/push_client_channel.h"

#include <utility>

#include "base/stl_util.h"
#include "build/build_config.h"
#include "components/invalidation/impl/notifier_reason_util.h"
#include "google/cacheinvalidation/client_gateway.pb.h"
#include "google/cacheinvalidation/types.pb.h"
#include "jingle/notifier/listener/push_client.h"
#include "net/traffic_annotation/network_traffic_annotation.h"

namespace syncer {

namespace {

const char kBotJid[] = "tango@bot.talk.google.com";
const char kChannelName[] = "tango_raw";

}  // namespace

PushClientChannel::PushClientChannel(
    std::unique_ptr<notifier::PushClient> push_client)
    : push_client_(std::move(push_client)),
      scheduling_hash_(0),
      sent_messages_count_(0) {
  push_client_->AddObserver(this);
  notifier::Subscription subscription;
  subscription.channel = kChannelName;
  subscription.from = "";
  notifier::SubscriptionList subscriptions;
  subscriptions.push_back(subscription);
  push_client_->UpdateSubscriptions(subscriptions);
}

PushClientChannel::~PushClientChannel() {
  push_client_->RemoveObserver(this);
}

void PushClientChannel::UpdateCredentials(
    const std::string& email, const std::string& token) {
  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("puch_client_channel", R"(
        semantics {
          sender: "Push Client Channel"
          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 "
            "XMPP PushClient to communicate with server."
          trigger:
            "Initial communication happens after browser startup to register "
            "client device with server and update online status. Consecutive "
            "communications are triggered by heartbeat timer and push "
            "notifications from server."
          data:
            "Protocol buffers including server generated client_token, "
            "ObjectIds identifying subscriptions, and versions for these "
            "subscriptions. ObjectId is not unique to user. 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 is disabled by default and cannot be enabled by "
            "settings. It is controlled by sync server experiments."
          chrome_policy {
            SyncDisabled {
              SyncDisabled: true
            }
          }
        }
    )");
  push_client_->UpdateCredentials(email, token, traffic_annotation);
}

int PushClientChannel::GetInvalidationClientType() {
#if defined(OS_IOS)
  return ipc::invalidation::ClientType::CHROME_SYNC_IOS;
#else
  return ipc::invalidation::ClientType::CHROME_SYNC;
#endif
}

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

void PushClientChannel::SendMessage(const std::string& message) {
  std::string encoded_message;
  EncodeMessage(&encoded_message, message, service_context_, scheduling_hash_);

  notifier::Recipient recipient;
  recipient.to = kBotJid;
  notifier::Notification notification;
  notification.channel = kChannelName;
  notification.recipients.push_back(recipient);
  notification.data = encoded_message;
  push_client_->SendNotification(notification);
  sent_messages_count_++;
}

void PushClientChannel::OnNotificationsEnabled() {
  NotifyNetworkStatusChange(true);
  NotifyChannelStateChange(INVALIDATIONS_ENABLED);
}

void PushClientChannel::OnNotificationsDisabled(
    notifier::NotificationsDisabledReason reason) {
  NotifyNetworkStatusChange(false);
  NotifyChannelStateChange(FromNotifierReason(reason));
}

void PushClientChannel::OnIncomingNotification(
    const notifier::Notification& notification) {
  std::string message;
  std::string service_context;
  int64_t scheduling_hash;
  if (!DecodeMessage(
           notification.data, &message, &service_context, &scheduling_hash)) {
    DLOG(ERROR) << "Could not parse ClientGatewayMessage";
    return;
  }
  if (DeliverIncomingMessage(message)) {
    service_context_ = service_context;
    scheduling_hash_ = scheduling_hash;
  }
}

const std::string& PushClientChannel::GetServiceContextForTest() const {
  return service_context_;
}

int64_t PushClientChannel::GetSchedulingHashForTest() const {
  return scheduling_hash_;
}

std::string PushClientChannel::EncodeMessageForTest(
    const std::string& message,
    const std::string& service_context,
    int64_t scheduling_hash) {
  std::string encoded_message;
  EncodeMessage(&encoded_message, message, service_context, scheduling_hash);
  return encoded_message;
}

bool PushClientChannel::DecodeMessageForTest(const std::string& data,
                                             std::string* message,
                                             std::string* service_context,
                                             int64_t* scheduling_hash) {
  return DecodeMessage(data, message, service_context, scheduling_hash);
}

void PushClientChannel::EncodeMessage(std::string* encoded_message,
                                      const std::string& message,
                                      const std::string& service_context,
                                      int64_t scheduling_hash) {
  ipc::invalidation::ClientGatewayMessage envelope;
  envelope.set_is_client_to_server(true);
  if (!service_context.empty()) {
    envelope.set_service_context(service_context);
    envelope.set_rpc_scheduling_hash(scheduling_hash);
  }
  envelope.set_network_message(message);
  envelope.SerializeToString(encoded_message);
}

bool PushClientChannel::DecodeMessage(const std::string& data,
                                      std::string* message,
                                      std::string* service_context,
                                      int64_t* scheduling_hash) {
  ipc::invalidation::ClientGatewayMessage envelope;
  if (!envelope.ParseFromString(data)) {
    return false;
  }
  *message = envelope.network_message();
  if (envelope.has_service_context()) {
    *service_context = envelope.service_context();
  }
  if (envelope.has_rpc_scheduling_hash()) {
    *scheduling_hash = envelope.rpc_scheduling_hash();
  }
  return true;
}

std::unique_ptr<base::DictionaryValue> PushClientChannel::CollectDebugData()
    const {
  std::unique_ptr<base::DictionaryValue> status(new base::DictionaryValue);
  status->SetString("PushClientChannel.NetworkChannel", "Push Client");
  status->SetInteger("PushClientChannel.SentMessages", sent_messages_count_);
  status->SetInteger("PushClientChannel.ReceivedMessages",
                     SyncNetworkChannel::GetReceivedMessagesCount());
  return status;
}

}  // namespace syncer
