// Copyright 2019 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 "extensions/browser/task_queue_util.h"

#include "content/public/browser/browser_context.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/lazy_background_task_queue.h"
#include "extensions/browser/lazy_context_id.h"
#include "extensions/browser/service_worker_task_queue.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/manifest_handlers/incognito_info.h"

namespace extensions {

namespace {

// Get the ServiceWorkerTaskQueue instance for the BrowserContext.
//
ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForBrowserContext(
    content::BrowserContext* browser_context,
    bool is_split_mode) {
  content::BrowserContext* context_to_use = browser_context;
  // Incognito extensions in split mode use their own task queue, while those
  // in spanning mode use the task queue of the original BrowserContext.
  if (browser_context->IsOffTheRecord() && !is_split_mode) {
    context_to_use =
        ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context);
  }
  return ServiceWorkerTaskQueue::Get(context_to_use);
}

// Get the ServiceWorkerTaskQueue instance for the extension.
//
// Only call this for a SW-based extension.
ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForExtension(
    content::BrowserContext* browser_context,
    const Extension* extension) {
  DCHECK(BackgroundInfo::IsServiceWorkerBased(extension));
  return GetServiceWorkerTaskQueueForBrowserContext(
      browser_context, IncognitoInfo::IsSplitMode(extension));
}

// Get the ServiceWorkerTaskQueue instance for the extension ID.
//
// Only call this for a SW-based extension.
ServiceWorkerTaskQueue* GetServiceWorkerTaskQueueForExtensionId(
    content::BrowserContext* browser_context,
    const ExtensionId& extension_id) {
  // Incognito extensions in split mode use their own task queue, while those
  // in spanning mode use the task queue of the original BrowserContext.
  // This is an optimization to avoid looking up an Extension instance,
  // since we only need it for the off-the-record case.
  if (!browser_context->IsOffTheRecord()) {
    return ServiceWorkerTaskQueue::Get(browser_context);
  }

  const Extension* extension = ExtensionRegistry::Get(browser_context)
                                   ->enabled_extensions()
                                   .GetByID(extension_id);
  DCHECK(extension);
  return GetServiceWorkerTaskQueueForExtension(browser_context, extension);
}

// Use a pointer-to-member function so we can use the same logic for the
// activation and deactivation paths.
using TaskQueueFunction = void (ServiceWorkerTaskQueue::*)(const Extension*);

void DoTaskQueueFunction(content::BrowserContext* browser_context,
                         const Extension* extension,
                         TaskQueueFunction function) {
  // This is only necessary for service worker-based extensions.
  if (!BackgroundInfo::IsServiceWorkerBased(extension))
    return;

  ServiceWorkerTaskQueue* const queue =
      ServiceWorkerTaskQueue::Get(browser_context);
  (queue->*function)(extension);

  // There is a separate task queue for the off-the-record context
  // for any extension running in split mode.
  if (!ExtensionsBrowserClient::Get()->HasOffTheRecordContext(
          browser_context) ||
      !IncognitoInfo::IsSplitMode(extension) ||
      !ExtensionsBrowserClient::Get()->IsExtensionIncognitoEnabled(
          extension->id(), browser_context)) {
    return;
  }

  content::BrowserContext* off_the_record_context =
      ExtensionsBrowserClient::Get()->GetOffTheRecordContext(browser_context);
  DCHECK(off_the_record_context);
  ServiceWorkerTaskQueue* const off_the_record_queue =
      ServiceWorkerTaskQueue::Get(off_the_record_context);
  (off_the_record_queue->*function)(extension);
}

}  // anonymous namespace

LazyContextTaskQueue* GetTaskQueueForLazyContextId(
    const LazyContextId& context_id) {
  if (context_id.is_for_event_page())
    return LazyBackgroundTaskQueue::Get(context_id.browser_context());

  DCHECK(context_id.is_for_service_worker());
  return GetServiceWorkerTaskQueueForExtensionId(context_id.browser_context(),
                                                 context_id.extension_id());
}

void ActivateTaskQueueForExtension(content::BrowserContext* browser_context,
                                   const Extension* extension) {
  DCHECK(!browser_context->IsOffTheRecord());
  DoTaskQueueFunction(browser_context, extension,
                      &ServiceWorkerTaskQueue::ActivateExtension);
}

void DeactivateTaskQueueForExtension(content::BrowserContext* browser_context,
                                     const Extension* extension) {
  DCHECK(!browser_context->IsOffTheRecord());
  DoTaskQueueFunction(browser_context, extension,
                      &ServiceWorkerTaskQueue::DeactivateExtension);
}

}  // namespace extensions
