// 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 "chrome/browser/extensions/extension_gcm_app_handler.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/gcm/gcm_api.h"
#include "chrome/browser/gcm/gcm_profile_service_factory.h"
#include "chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/gcm_driver/gcm_profile_service.h"
#include "components/gcm_driver/instance_id/instance_id_driver.h"
#include "components/gcm_driver/instance_id/instance_id_profile_service.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/permissions/permissions_data.h"

namespace extensions {

namespace {

const char kDummyAppId[] = "extension.guard.dummy.id";

base::LazyInstance<BrowserContextKeyedAPIFactory<ExtensionGCMAppHandler>>::
    DestructorAtExit g_extension_gcm_app_handler_factory =
        LAZY_INSTANCE_INITIALIZER;

bool IsGCMPermissionEnabled(const Extension* extension) {
  return extension->permissions_data()->HasAPIPermission(APIPermission::kGcm);
}

}  // namespace


// static
BrowserContextKeyedAPIFactory<ExtensionGCMAppHandler>*
ExtensionGCMAppHandler::GetFactoryInstance() {
  return g_extension_gcm_app_handler_factory.Pointer();
}

ExtensionGCMAppHandler::ExtensionGCMAppHandler(content::BrowserContext* context)
    : profile_(Profile::FromBrowserContext(context)),
      extension_registry_observer_(this),
      weak_factory_(this) {
  extension_registry_observer_.Add(ExtensionRegistry::Get(profile_));
  js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
}

ExtensionGCMAppHandler::~ExtensionGCMAppHandler() = default;

void ExtensionGCMAppHandler::Shutdown() {
  const ExtensionSet& enabled_extensions =
      ExtensionRegistry::Get(profile_)->enabled_extensions();
  for (ExtensionSet::const_iterator extension = enabled_extensions.begin();
       extension != enabled_extensions.end();
       ++extension) {
    if (IsGCMPermissionEnabled(extension->get()))
      GetGCMDriver()->RemoveAppHandler((*extension)->id());
  }
}

void ExtensionGCMAppHandler::ShutdownHandler() {
  js_event_router_.reset();
}

void ExtensionGCMAppHandler::OnStoreReset() {
  // TODO(crbug.com/661660): Notify the extension somehow that its registration
  // was invalidated and deleted?
}

void ExtensionGCMAppHandler::OnMessage(const std::string& app_id,
                                       const gcm::IncomingMessage& message) {
  js_event_router_->OnMessage(app_id, message);
}

void ExtensionGCMAppHandler::OnMessagesDeleted(const std::string& app_id) {
  js_event_router_->OnMessagesDeleted(app_id);
}

void ExtensionGCMAppHandler::OnSendError(
    const std::string& app_id,
    const gcm::GCMClient::SendErrorDetails& send_error_details) {
  js_event_router_->OnSendError(app_id, send_error_details);
}

void ExtensionGCMAppHandler::OnSendAcknowledged(
    const std::string& app_id,
    const std::string& message_id) {
  // This event is not exposed to JS API. It terminates here.
}

void ExtensionGCMAppHandler::OnExtensionLoaded(
    content::BrowserContext* browser_context,
    const Extension* extension) {
  if (IsGCMPermissionEnabled(extension))
    AddAppHandler(extension->id());
}

void ExtensionGCMAppHandler::OnExtensionUnloaded(
    content::BrowserContext* browser_context,
    const Extension* extension,
    UnloadedExtensionReason reason) {
  if (!IsGCMPermissionEnabled(extension))
    return;

  if (reason == UnloadedExtensionReason::UPDATE &&
      GetGCMDriver()->app_handlers().size() >= 1) {
    // When the extension is being updated, it will be first unloaded and then
    // loaded again by ExtensionService::AddExtension. If the app handler for
    // this extension is the only handler, removing it and adding it again will
    // cause the GCM service being stopped and restarted unnecessarily. To work
    // around this, we add a dummy app handler to guard against it. This dummy
    // app handler will be removed once the extension loading logic is done.
    //
    // Note that this dummy app handler is added when there is at least one
    // handler. This is because there might be a built-in app handler, like
    // GCMAccountMapper, which is automatically added and removed by
    // GCMDriverDesktop.
    //
    // Also note that the GCM message routing will not be interruptted during
    // the update process since unloading and reloading extension are done in
    // the single function ExtensionService::AddExtension.
    AddDummyAppHandler();

    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&ExtensionGCMAppHandler::RemoveDummyAppHandler,
                       weak_factory_.GetWeakPtr()));
  }

  // When the extention is being uninstalled, it will be unloaded first. We
  // should not remove the app handler in this case and it will be handled
  // in OnExtensionUninstalled.
  if (reason != UnloadedExtensionReason::UNINSTALL)
    RemoveAppHandler(extension->id());
}

void ExtensionGCMAppHandler::OnExtensionUninstalled(
    content::BrowserContext* browser_context,
    const Extension* extension,
    extensions::UninstallReason reason) {
  if (IsGCMPermissionEnabled(extension)) {
    // Let's first remove InstanceID data. GCM unregistration will be triggered
    // after the asynchronous call is returned in OnDeleteIDCompleted.
    GetInstanceIDDriver()->GetInstanceID(extension->id())->DeleteID(
        base::Bind(&ExtensionGCMAppHandler::OnDeleteIDCompleted,
                   weak_factory_.GetWeakPtr(),
                   extension->id()));
  }
}

void ExtensionGCMAppHandler::AddDummyAppHandler() {
  AddAppHandler(kDummyAppId);
}

void ExtensionGCMAppHandler::RemoveDummyAppHandler() {
  RemoveAppHandler(kDummyAppId);
}

gcm::GCMDriver* ExtensionGCMAppHandler::GetGCMDriver() const {
  return gcm::GCMProfileServiceFactory::GetForProfile(profile_)->driver();
}

instance_id::InstanceIDDriver* ExtensionGCMAppHandler::GetInstanceIDDriver()
    const {
  return instance_id::InstanceIDProfileServiceFactory::GetForProfile(profile_)->
      driver();
}

void ExtensionGCMAppHandler::OnUnregisterCompleted(
    const std::string& app_id, gcm::GCMClient::Result result) {
  RemoveAppHandler(app_id);
}

void ExtensionGCMAppHandler::OnDeleteIDCompleted(
    const std::string& app_id, instance_id::InstanceID::Result result) {
  GetGCMDriver()->Unregister(
      app_id,
      base::Bind(&ExtensionGCMAppHandler::OnUnregisterCompleted,
                 weak_factory_.GetWeakPtr(),
                 app_id));

  // InstanceIDDriver::RemoveInstanceID will delete the InstanceID itself.
  // Postpone to do it outside this calling context to avoid any risk to
  // the caller.
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&ExtensionGCMAppHandler::RemoveInstanceID,
                                weak_factory_.GetWeakPtr(), app_id));
}

void ExtensionGCMAppHandler::RemoveInstanceID(const std::string& app_id) {
  GetInstanceIDDriver()->RemoveInstanceID(app_id);
}

void ExtensionGCMAppHandler::AddAppHandler(const std::string& app_id) {
  GetGCMDriver()->AddAppHandler(app_id, this);
}

void ExtensionGCMAppHandler::RemoveAppHandler(const std::string& app_id) {
  GetGCMDriver()->RemoveAppHandler(app_id);
}

}  // namespace extensions
