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

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/sys_byteorder.h"
#include "base/time/time.h"
#include "google_apis/gcm/base/encryptor.h"
#include "net/base/ip_endpoint.h"

namespace gcm {

FakeGCMClient::FakeGCMClient(
    StartMode start_mode,
    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
    const scoped_refptr<base::SequencedTaskRunner>& io_thread)
    : delegate_(NULL),
      status_(UNINITIALIZED),
      start_mode_(start_mode),
      ui_thread_(ui_thread),
      io_thread_(io_thread),
      weak_ptr_factory_(this) {
}

FakeGCMClient::~FakeGCMClient() {
}

void FakeGCMClient::Initialize(
    const ChromeBuildInfo& chrome_build_info,
    const base::FilePath& store_path,
    const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
    const scoped_refptr<net::URLRequestContextGetter>&
        url_request_context_getter,
    scoped_ptr<Encryptor> encryptor,
    Delegate* delegate) {
  delegate_ = delegate;
}

void FakeGCMClient::Start() {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());
  DCHECK_NE(STARTED, status_);

  if (start_mode_ == DELAY_START)
    return;
  DoLoading();
}

void FakeGCMClient::DoLoading() {
  status_ = STARTED;
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::CheckinFinished,
                 weak_ptr_factory_.GetWeakPtr()));
}

void FakeGCMClient::Stop() {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());
  status_ = STOPPED;
  delegate_->OnDisconnected();
}

void FakeGCMClient::CheckOut() {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());
  status_ = CHECKED_OUT;
}

void FakeGCMClient::Register(const std::string& app_id,
                             const std::vector<std::string>& sender_ids) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  std::string registration_id = GetRegistrationIdFromSenderIds(sender_ids);
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::RegisterFinished,
                 weak_ptr_factory_.GetWeakPtr(),
                 app_id,
                 registration_id));
}

void FakeGCMClient::Unregister(const std::string& app_id) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::UnregisterFinished,
                 weak_ptr_factory_.GetWeakPtr(),
                 app_id));
}

void FakeGCMClient::Send(const std::string& app_id,
                         const std::string& receiver_id,
                         const OutgoingMessage& message) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::SendFinished,
                 weak_ptr_factory_.GetWeakPtr(),
                 app_id,
                 message));
}

void FakeGCMClient::SetRecording(bool recording) {
}

void FakeGCMClient::ClearActivityLogs() {
}

GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
  return GCMClient::GCMStatistics();
}

void FakeGCMClient::PerformDelayedLoading() {
  DCHECK(ui_thread_->RunsTasksOnCurrentThread());

  io_thread_->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::DoLoading, weak_ptr_factory_.GetWeakPtr()));
}

void FakeGCMClient::ReceiveMessage(const std::string& app_id,
                                   const IncomingMessage& message) {
  DCHECK(ui_thread_->RunsTasksOnCurrentThread());

  io_thread_->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::MessageReceived,
                 weak_ptr_factory_.GetWeakPtr(),
                 app_id,
                 message));
}

void FakeGCMClient::DeleteMessages(const std::string& app_id) {
  DCHECK(ui_thread_->RunsTasksOnCurrentThread());

  io_thread_->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::MessagesDeleted,
                 weak_ptr_factory_.GetWeakPtr(),
                 app_id));
}

// static
std::string FakeGCMClient::GetRegistrationIdFromSenderIds(
    const std::vector<std::string>& sender_ids) {
  // GCMService normalizes the sender IDs by making them sorted.
  std::vector<std::string> normalized_sender_ids = sender_ids;
  std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());

  // Simulate the registration_id by concaternating all sender IDs.
  // Set registration_id to empty to denote an error if sender_ids contains a
  // hint.
  std::string registration_id;
  if (sender_ids.size() != 1 ||
      sender_ids[0].find("error") == std::string::npos) {
    for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
      if (i > 0)
        registration_id += ",";
      registration_id += normalized_sender_ids[i];
    }
  }
  return registration_id;
}

void FakeGCMClient::CheckinFinished() {
  delegate_->OnGCMReady();
  delegate_->OnConnected(net::IPEndPoint());
}

void FakeGCMClient::RegisterFinished(const std::string& app_id,
                                     const std::string& registrion_id) {
  delegate_->OnRegisterFinished(
      app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
}

void FakeGCMClient::UnregisterFinished(const std::string& app_id) {
  delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS);
}

void FakeGCMClient::SendFinished(const std::string& app_id,
                                 const OutgoingMessage& message) {
  delegate_->OnSendFinished(app_id, message.id, SUCCESS);

  // Simulate send error if message id contains a hint.
  if (message.id.find("error") != std::string::npos) {
    SendErrorDetails send_error_details;
    send_error_details.message_id = message.id;
    send_error_details.result = NETWORK_ERROR;
    send_error_details.additional_data = message.data;
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeGCMClient::MessageSendError,
                   weak_ptr_factory_.GetWeakPtr(),
                   app_id,
                   send_error_details),
        base::TimeDelta::FromMilliseconds(200));
  }
}

void FakeGCMClient::MessageReceived(const std::string& app_id,
                                    const IncomingMessage& message) {
  if (delegate_)
    delegate_->OnMessageReceived(app_id, message);
}

void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
  if (delegate_)
    delegate_->OnMessagesDeleted(app_id);
}

void FakeGCMClient::MessageSendError(
    const std::string& app_id,
    const GCMClient::SendErrorDetails& send_error_details) {
  if (delegate_)
    delegate_->OnMessageSendError(app_id, send_error_details);
}

}  // namespace gcm
