// Copyright 2015 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 "chromeos/services/device_sync/cryptauth_gcm_manager_impl.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/services/device_sync/pref_names.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/prefs/pref_service.h"

namespace chromeos {

namespace device_sync {

namespace {

// The GCM app id identifies the client.
const char kCryptAuthGCMAppId[] = "com.google.chrome.cryptauth";

// The GCM sender id identifies the CryptAuth server.
const char kCryptAuthGCMSenderId[] = "381449029288";

// The 'registrationTickleType' key-value pair is present in GCM push
// messages. The values correspond to a server-side enum.
const char kRegistrationTickleTypeKey[] = "registrationTickleType";
const char kRegistrationTickleTypeForceEnrollment[] = "1";
const char kRegistrationTickleTypeUpdateEnrollment[] = "2";
const char kRegistrationTickleTypeDevicesSync[] = "3";

}  // namespace

// static
CryptAuthGCMManagerImpl::Factory*
    CryptAuthGCMManagerImpl::Factory::factory_instance_ = nullptr;

// static
std::unique_ptr<CryptAuthGCMManager>
CryptAuthGCMManagerImpl::Factory::NewInstance(gcm::GCMDriver* gcm_driver,
                                              PrefService* pref_service) {
  if (!factory_instance_)
    factory_instance_ = new Factory();

  return factory_instance_->BuildInstance(gcm_driver, pref_service);
}

// static
void CryptAuthGCMManagerImpl::Factory::SetInstanceForTesting(Factory* factory) {
  factory_instance_ = factory;
}

CryptAuthGCMManagerImpl::Factory::~Factory() = default;

std::unique_ptr<CryptAuthGCMManager>
CryptAuthGCMManagerImpl::Factory::BuildInstance(gcm::GCMDriver* gcm_driver,
                                                PrefService* pref_service) {
  return base::WrapUnique(
      new CryptAuthGCMManagerImpl(gcm_driver, pref_service));
}

CryptAuthGCMManagerImpl::CryptAuthGCMManagerImpl(gcm::GCMDriver* gcm_driver,
                                                 PrefService* pref_service)
    : gcm_driver_(gcm_driver),
      pref_service_(pref_service),
      registration_in_progress_(false),
      weak_ptr_factory_(this) {}

CryptAuthGCMManagerImpl::~CryptAuthGCMManagerImpl() {
  if (gcm_driver_->GetAppHandler(kCryptAuthGCMAppId) == this)
    gcm_driver_->RemoveAppHandler(kCryptAuthGCMAppId);
}

void CryptAuthGCMManagerImpl::StartListening() {
  if (gcm_driver_->GetAppHandler(kCryptAuthGCMAppId) == this) {
    PA_LOG(VERBOSE) << "GCM app handler already added";
    return;
  }

  gcm_driver_->AddAppHandler(kCryptAuthGCMAppId, this);
}

void CryptAuthGCMManagerImpl::RegisterWithGCM() {
  if (registration_in_progress_) {
    PA_LOG(VERBOSE) << "GCM Registration is already in progress";
    return;
  }

  PA_LOG(VERBOSE) << "Beginning GCM registration...";
  registration_in_progress_ = true;

  std::vector<std::string> sender_ids(1, kCryptAuthGCMSenderId);
  gcm_driver_->Register(
      kCryptAuthGCMAppId, sender_ids,
      base::Bind(&CryptAuthGCMManagerImpl::OnRegistrationCompleted,
                 weak_ptr_factory_.GetWeakPtr()));
}

std::string CryptAuthGCMManagerImpl::GetRegistrationId() {
  return pref_service_->GetString(prefs::kCryptAuthGCMRegistrationId);
}

void CryptAuthGCMManagerImpl::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void CryptAuthGCMManagerImpl::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

void CryptAuthGCMManagerImpl::ShutdownHandler() {}

void CryptAuthGCMManagerImpl::OnStoreReset() {
  // We will automatically re-register to GCM and re-enroll the new registration
  // ID to Cryptauth during the next scheduled sync.
  pref_service_->ClearPref(prefs::kCryptAuthGCMRegistrationId);
}

void CryptAuthGCMManagerImpl::OnMessage(const std::string& app_id,
                                        const gcm::IncomingMessage& message) {
  std::vector<std::string> fields;
  for (const auto& kv : message.data) {
    fields.push_back(std::string(kv.first) + ": " + std::string(kv.second));
  }

  PA_LOG(VERBOSE) << "GCM message received:\n"
                  << "  sender_id: " << message.sender_id << "\n"
                  << "  collapse_key: " << message.collapse_key << "\n"
                  << "  data:\n    " << base::JoinString(fields, "\n    ");

  if (message.data.find(kRegistrationTickleTypeKey) == message.data.end()) {
    PA_LOG(WARNING) << "GCM message does not contain 'registrationTickleType'.";
  } else {
    std::string tickle_type = message.data.at(kRegistrationTickleTypeKey);
    if (tickle_type == kRegistrationTickleTypeForceEnrollment ||
        tickle_type == kRegistrationTickleTypeUpdateEnrollment) {
      // These tickle types correspond to re-enrollment messages.
      for (auto& observer : observers_)
        observer.OnReenrollMessage();
    } else if (tickle_type == kRegistrationTickleTypeDevicesSync) {
      for (auto& observer : observers_)
        observer.OnResyncMessage();
    } else {
      PA_LOG(WARNING) << "Unknown tickle type in GCM message.";
    }
  }
}

void CryptAuthGCMManagerImpl::OnMessagesDeleted(const std::string& app_id) {}

void CryptAuthGCMManagerImpl::OnSendError(
    const std::string& app_id,
    const gcm::GCMClient::SendErrorDetails& details) {
  NOTREACHED();
}

void CryptAuthGCMManagerImpl::OnSendAcknowledged(
    const std::string& app_id,
    const std::string& message_id) {
  NOTREACHED();
}

void CryptAuthGCMManagerImpl::OnRegistrationCompleted(
    const std::string& registration_id,
    gcm::GCMClient::Result result) {
  registration_in_progress_ = false;
  if (result != gcm::GCMClient::SUCCESS) {
    PA_LOG(WARNING) << "GCM registration failed with result="
                    << static_cast<int>(result);
    for (auto& observer : observers_)
      observer.OnGCMRegistrationResult(false);
    return;
  }

  PA_LOG(VERBOSE) << "GCM registration success, registration_id="
                  << registration_id;
  pref_service_->SetString(prefs::kCryptAuthGCMRegistrationId, registration_id);
  for (auto& observer : observers_)
    observer.OnGCMRegistrationResult(true);
}

}  // namespace device_sync

}  // namespace chromeos
