// 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 "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/invalidation/impl/gcm_invalidation_bridge.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/identity_provider.h"

namespace invalidation {
namespace {
// For 3rd party developers SenderId should come from application dashboard when
// server side application is registered with Google. Android invalidations use
// legacy format where gmail account can be specificed. Below value is copied
// from Android.
const char kInvalidationsSenderId[] = "ipc.invalidation@gmail.com";
// In Android world AppId is provided by operating system and should
// match package name and hash of application. In desktop world these values
// are arbitrary and not verified/enforced by registration service (yet).
const char kInvalidationsAppId[] = "com.google.chrome.invalidations";

// Cacheinvalidation specific gcm message keys.
const char kContentKey[] = "content";
const char kEchoTokenKey[] = "echo-token";
}  // namespace

// Core should be very simple class that implements GCMNetwrokChannelDelegate
// and passes all calls to GCMInvalidationBridge. All calls should be serialized
// through GCMInvalidationBridge to avoid race conditions.
class GCMInvalidationBridge::Core : public syncer::GCMNetworkChannelDelegate,
                                    public base::NonThreadSafe {
 public:
  Core(base::WeakPtr<GCMInvalidationBridge> bridge,
       scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
  ~Core() override;

  // syncer::GCMNetworkChannelDelegate implementation.
  void Initialize(ConnectionStateCallback connection_state_callback,
                  base::Closure store_reset_callback) override;
  void RequestToken(RequestTokenCallback callback) override;
  void InvalidateToken(const std::string& token) override;
  void Register(RegisterCallback callback) override;
  void SetMessageReceiver(MessageCallback callback) override;

  void RequestTokenFinished(RequestTokenCallback callback,
                            const GoogleServiceAuthError& error,
                            const std::string& token);

  void RegisterFinished(RegisterCallback callback,
                        const std::string& registration_id,
                        gcm::GCMClient::Result result);

  void OnIncomingMessage(const std::string& message,
                         const std::string& echo_token);

  void OnConnectionStateChanged(bool online);
  void OnStoreReset();

 private:
  base::WeakPtr<GCMInvalidationBridge> bridge_;
  scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;

  MessageCallback message_callback_;
  ConnectionStateCallback connection_state_callback_;
  base::Closure store_reset_callback_;

  base::WeakPtrFactory<Core> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(Core);
};

GCMInvalidationBridge::Core::Core(
    base::WeakPtr<GCMInvalidationBridge> bridge,
    scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
    : bridge_(bridge),
      ui_thread_task_runner_(ui_thread_task_runner),
      weak_factory_(this) {
  // Core is created on UI thread but all calls happen on IO thread.
  DetachFromThread();
}

GCMInvalidationBridge::Core::~Core() {}

void GCMInvalidationBridge::Core::Initialize(
    ConnectionStateCallback connection_state_callback,
    base::Closure store_reset_callback) {
  DCHECK(CalledOnValidThread());
  connection_state_callback_ = connection_state_callback;
  store_reset_callback_ = store_reset_callback;
  // Pass core WeapPtr and TaskRunner to GCMInvalidationBridge for it to be able
  // to post back.
  ui_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::CoreInitializationDone,
                 bridge_,
                 weak_factory_.GetWeakPtr(),
                 base::ThreadTaskRunnerHandle::Get()));
}

void GCMInvalidationBridge::Core::RequestToken(RequestTokenCallback callback) {
  DCHECK(CalledOnValidThread());
  ui_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::RequestToken, bridge_, callback));
}

void GCMInvalidationBridge::Core::InvalidateToken(const std::string& token) {
  DCHECK(CalledOnValidThread());
  ui_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::InvalidateToken, bridge_, token));
}

void GCMInvalidationBridge::Core::Register(RegisterCallback callback) {
  DCHECK(CalledOnValidThread());
  ui_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Register, bridge_, callback));
}

void GCMInvalidationBridge::Core::SetMessageReceiver(MessageCallback callback) {
  message_callback_ = callback;
  ui_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::SubscribeForIncomingMessages,
                 bridge_));
}

void GCMInvalidationBridge::Core::RequestTokenFinished(
    RequestTokenCallback callback,
    const GoogleServiceAuthError& error,
    const std::string& token) {
  DCHECK(CalledOnValidThread());
  callback.Run(error, token);
}

void GCMInvalidationBridge::Core::RegisterFinished(
    RegisterCallback callback,
    const std::string& registration_id,
    gcm::GCMClient::Result result) {
  DCHECK(CalledOnValidThread());
  callback.Run(registration_id, result);
}

void GCMInvalidationBridge::Core::OnIncomingMessage(
    const std::string& message,
    const std::string& echo_token) {
  DCHECK(!message_callback_.is_null());
  message_callback_.Run(message, echo_token);
}

void GCMInvalidationBridge::Core::OnConnectionStateChanged(bool online) {
  if (!connection_state_callback_.is_null()) {
    connection_state_callback_.Run(online);
  }
}

void GCMInvalidationBridge::Core::OnStoreReset() {
  if (!store_reset_callback_.is_null()) {
    store_reset_callback_.Run();
  }
}

GCMInvalidationBridge::GCMInvalidationBridge(
    gcm::GCMDriver* gcm_driver,
    IdentityProvider* identity_provider)
    : OAuth2TokenService::Consumer("gcm_network_channel"),
      gcm_driver_(gcm_driver),
      identity_provider_(identity_provider),
      subscribed_for_incoming_messages_(false),
      weak_factory_(this) {}

GCMInvalidationBridge::~GCMInvalidationBridge() {
  if (subscribed_for_incoming_messages_) {
    gcm_driver_->RemoveAppHandler(kInvalidationsAppId);
    gcm_driver_->RemoveConnectionObserver(this);
  }
}

std::unique_ptr<syncer::GCMNetworkChannelDelegate>
GCMInvalidationBridge::CreateDelegate() {
  DCHECK(CalledOnValidThread());
  return base::MakeUnique<Core>(weak_factory_.GetWeakPtr(),
                                base::ThreadTaskRunnerHandle::Get());
}

void GCMInvalidationBridge::CoreInitializationDone(
    base::WeakPtr<Core> core,
    scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner) {
  DCHECK(CalledOnValidThread());
  core_ = core;
  core_thread_task_runner_ = core_thread_task_runner;
}

void GCMInvalidationBridge::RequestToken(
    syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) {
  DCHECK(CalledOnValidThread());
  if (access_token_request_ != NULL) {
    // Report previous request as cancelled.
    GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
    std::string access_token;
    core_thread_task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
                   core_,
                   request_token_callback_,
                   error,
                   access_token));
  }
  request_token_callback_ = callback;
  OAuth2TokenService::ScopeSet scopes;
  scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
  access_token_request_ = identity_provider_->GetTokenService()->StartRequest(
      identity_provider_->GetActiveAccountId(), scopes, this);
}

void GCMInvalidationBridge::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const std::string& access_token,
    const base::Time& expiration_time) {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(access_token_request_.get(), request);
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
                 core_,
                 request_token_callback_,
                 GoogleServiceAuthError::AuthErrorNone(),
                 access_token));
  request_token_callback_.Reset();
  access_token_request_.reset();
}

void GCMInvalidationBridge::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  DCHECK(CalledOnValidThread());
  DCHECK_EQ(access_token_request_.get(), request);
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
                 core_,
                 request_token_callback_,
                 error,
                 std::string()));
  request_token_callback_.Reset();
  access_token_request_.reset();
}

void GCMInvalidationBridge::InvalidateToken(const std::string& token) {
  DCHECK(CalledOnValidThread());
  OAuth2TokenService::ScopeSet scopes;
  scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
  identity_provider_->GetTokenService()->InvalidateAccessToken(
      identity_provider_->GetActiveAccountId(), scopes, token);
}

void GCMInvalidationBridge::Register(
    syncer::GCMNetworkChannelDelegate::RegisterCallback callback) {
  DCHECK(CalledOnValidThread());
  // No-op if GCMClient is disabled.
  if (gcm_driver_ == NULL)
    return;

  std::vector<std::string> sender_ids;
  sender_ids.push_back(kInvalidationsSenderId);
  gcm_driver_->Register(kInvalidationsAppId,
                         sender_ids,
                         base::Bind(&GCMInvalidationBridge::RegisterFinished,
                                    weak_factory_.GetWeakPtr(),
                                    callback));
}

void GCMInvalidationBridge::RegisterFinished(
    syncer::GCMNetworkChannelDelegate::RegisterCallback callback,
    const std::string& registration_id,
    gcm::GCMClient::Result result) {
  DCHECK(CalledOnValidThread());
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::RegisterFinished,
                 core_,
                 callback,
                 registration_id,
                 result));
}

void GCMInvalidationBridge::Unregister() {
  DCHECK(CalledOnValidThread());
  // No-op if GCMClient is disabled.
  if (gcm_driver_ == NULL)
    return;

  gcm_driver_->Unregister(
      kInvalidationsAppId,
      base::Bind(&GCMInvalidationBridge::UnregisterFinishedNoOp));
}

// static
void GCMInvalidationBridge::UnregisterFinishedNoOp(
    gcm::GCMClient::Result result) {
  // No-op.
}

void GCMInvalidationBridge::SubscribeForIncomingMessages() {
  // No-op if GCMClient is disabled.
  if (gcm_driver_ == NULL)
    return;

  DCHECK(!subscribed_for_incoming_messages_);
  gcm_driver_->AddAppHandler(kInvalidationsAppId, this);
  gcm_driver_->AddConnectionObserver(this);
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::OnConnectionStateChanged,
                 core_,
                 gcm_driver_->IsConnected()));

  subscribed_for_incoming_messages_ = true;
}

void GCMInvalidationBridge::ShutdownHandler() {
  // Nothing to do.
}

void GCMInvalidationBridge::OnStoreReset() {
  core_thread_task_runner_->PostTask(
      FROM_HERE, base::Bind(&GCMInvalidationBridge::Core::OnStoreReset, core_));
}

void GCMInvalidationBridge::OnMessage(const std::string& app_id,
                                      const gcm::IncomingMessage& message) {
  gcm::MessageData::const_iterator it;
  std::string content;
  std::string echo_token;
  it = message.data.find(kContentKey);
  if (it != message.data.end())
    content = it->second;
  it = message.data.find(kEchoTokenKey);
  if (it != message.data.end())
    echo_token = it->second;

  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::OnIncomingMessage,
                 core_,
                 content,
                 echo_token));
}

void GCMInvalidationBridge::OnMessagesDeleted(const std::string& app_id) {
  // Cacheinvalidation doesn't use long lived non-collapsable messages with GCM.
  // Android implementation of cacheinvalidation doesn't handle MessagesDeleted
  // callback so this should be no-op in desktop version as well.
}

void GCMInvalidationBridge::OnSendError(
    const std::string& app_id,
    const gcm::GCMClient::SendErrorDetails& send_error_details) {
  // cacheinvalidation doesn't send messages over GCM.
  NOTREACHED();
}

void GCMInvalidationBridge::OnSendAcknowledged(
    const std::string& app_id,
    const std::string& message_id) {
  // cacheinvalidation doesn't send messages over GCM.
  NOTREACHED();
}

void GCMInvalidationBridge::OnConnected(const net::IPEndPoint& ip_endpoint) {
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(
          &GCMInvalidationBridge::Core::OnConnectionStateChanged, core_, true));
}

void GCMInvalidationBridge::OnDisconnected() {
  core_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&GCMInvalidationBridge::Core::OnConnectionStateChanged,
                 core_,
                 false));
}

}  // namespace invalidation
