// 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 <stddef.h>

#include <algorithm>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "google_apis/gcm/base/encryptor.h"
#include "google_apis/gcm/engine/account_mapping.h"
#include "net/base/ip_endpoint.h"

namespace gcm {

// static
std::string FakeGCMClient::GenerateGCMRegistrationID(
    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;
}

// static
std::string FakeGCMClient::GenerateInstanceIDToken(
    const std::string& authorized_entity, const std::string& scope) {
  if (authorized_entity.find("error") != std::string::npos)
    return "";
  std::string token(authorized_entity);
  token += ",";
  token += scope;
  return token;
}

FakeGCMClient::FakeGCMClient(
    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
    const scoped_refptr<base::SequencedTaskRunner>& io_thread)
    : delegate_(NULL),
      started_(false),
      start_mode_(DELAYED_START),
      start_mode_overridding_(RESPECT_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,
    std::unique_ptr<Encryptor> encryptor,
    Delegate* delegate) {
  product_category_for_subtypes_ =
      chrome_build_info.product_category_for_subtypes;
  delegate_ = delegate;
}

void FakeGCMClient::Start(StartMode start_mode) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  if (started_)
    return;

  if (start_mode == IMMEDIATE_START)
    start_mode_ = IMMEDIATE_START;
  if (start_mode_ == DELAYED_START ||
      start_mode_overridding_ == FORCE_TO_ALWAYS_DELAY_START_GCM) {
    return;
  }

  DoStart();
}

void FakeGCMClient::DoStart() {
  started_ = true;
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::Started, weak_ptr_factory_.GetWeakPtr()));
}

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

void FakeGCMClient::Register(
    const linked_ptr<RegistrationInfo>& registration_info) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  std::string registration_id;

  GCMRegistrationInfo* gcm_registration_info =
      GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
  if (gcm_registration_info) {
    registration_id = GenerateGCMRegistrationID(
        gcm_registration_info->sender_ids);
  }

  InstanceIDTokenInfo* instance_id_token_info =
      InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
  if (instance_id_token_info) {
    registration_id = GenerateInstanceIDToken(
        instance_id_token_info->authorized_entity,
        instance_id_token_info->scope);
  }

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(&FakeGCMClient::RegisterFinished,
                            weak_ptr_factory_.GetWeakPtr(), registration_info,
                            registration_id));
}

bool FakeGCMClient::ValidateRegistration(
    const linked_ptr<RegistrationInfo>& registration_info,
    const std::string& registration_id) {
  return true;
}

void FakeGCMClient::Unregister(
    const linked_ptr<RegistrationInfo>& registration_info) {
  DCHECK(io_thread_->RunsTasksOnCurrentThread());

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::Bind(&FakeGCMClient::UnregisterFinished,
                            weak_ptr_factory_.GetWeakPtr(), registration_info));
}

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

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

void FakeGCMClient::RecordDecryptionFailure(
    const std::string& app_id,
    GCMEncryptionProvider::DecryptionResult result) {
  recorder_.RecordDecryptionFailure(app_id, result);
}

void FakeGCMClient::SetRecording(bool recording) {
  recorder_.set_is_recording(recording);
}

void FakeGCMClient::ClearActivityLogs() {
  recorder_.Clear();
}

GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
  GCMClient::GCMStatistics statistics;
  statistics.is_recording = recorder_.is_recording();

  recorder_.CollectActivities(&statistics.recorded_activities);
  return statistics;
}

void FakeGCMClient::SetAccountTokens(
    const std::vector<AccountTokenInfo>& account_tokens) {
}

void FakeGCMClient::UpdateAccountMapping(
    const AccountMapping& account_mapping) {
}

void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) {
}

void FakeGCMClient::SetLastTokenFetchTime(const base::Time& time) {
}

void FakeGCMClient::UpdateHeartbeatTimer(std::unique_ptr<base::Timer> timer) {}

void FakeGCMClient::AddInstanceIDData(const std::string& app_id,
                                      const std::string& instance_id,
                                      const std::string& extra_data) {
  instance_id_data_[app_id] = make_pair(instance_id, extra_data);
}

void FakeGCMClient::RemoveInstanceIDData(const std::string& app_id) {
  instance_id_data_.erase(app_id);
}

void FakeGCMClient::GetInstanceIDData(const std::string& app_id,
                                      std::string* instance_id,
                                      std::string* extra_data) {
  auto iter = instance_id_data_.find(app_id);
  if (iter == instance_id_data_.end()) {
    instance_id->clear();
    extra_data->clear();
    return;
  }

  *instance_id = iter->second.first;
  *extra_data = iter->second.second;
}

void FakeGCMClient::AddHeartbeatInterval(const std::string& scope,
                                         int interval_ms) {
}

void FakeGCMClient::RemoveHeartbeatInterval(const std::string& scope) {
}

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

  io_thread_->PostTask(
      FROM_HERE,
      base::Bind(&FakeGCMClient::DoStart, 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));
}

void FakeGCMClient::Started() {
  delegate_->OnGCMReady(std::vector<AccountMapping>(), base::Time());
  delegate_->OnConnected(net::IPEndPoint());
}

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

void FakeGCMClient::UnregisterFinished(
    const linked_ptr<RegistrationInfo>& registration_info) {
  delegate_->OnUnregisterFinished(registration_info, 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::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeGCMClient::MessageSendError,
                   weak_ptr_factory_.GetWeakPtr(), app_id, send_error_details),
        base::TimeDelta::FromMilliseconds(200));
  } else if(message.id.find("ack") != std::string::npos) {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&FakeGCMClient::SendAcknowledgement,
                   weak_ptr_factory_.GetWeakPtr(), app_id, message.id),
        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);
}

void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
                                        const std::string& message_id) {
  if (delegate_)
    delegate_->OnSendAcknowledged(app_id, message_id);
}

}  // namespace gcm
