// Copyright 2013 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/lazy_background_task_queue.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

// A ProcessManager that doesn't create background host pages.
class TestProcessManager : public ProcessManager {
 public:
  explicit TestProcessManager(Profile* profile)
      : ProcessManager(profile, profile->GetOriginalProfile()),
        create_count_(0) {}
  virtual ~TestProcessManager() {}

  int create_count() { return create_count_; }

  // ProcessManager overrides:
  virtual bool CreateBackgroundHost(const Extension* extension,
                                    const GURL& url) OVERRIDE {
    // Don't actually try to create a web contents.
    create_count_++;
    return false;
  }

 private:
  int create_count_;

  DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
};

// Derives from ExtensionServiceTestBase because ExtensionService is difficult
// to initialize alone.
class LazyBackgroundTaskQueueTest
    : public extensions::ExtensionServiceTestBase {
 public:
  LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
  virtual ~LazyBackgroundTaskQueueTest() {}

  int task_run_count() { return task_run_count_; }

  // A simple callback for AddPendingTask.
  void RunPendingTask(ExtensionHost* host) {
    task_run_count_++;
  }

  // Creates and registers an extension without a background page.
  scoped_refptr<Extension> CreateSimpleExtension() {
    scoped_refptr<Extension> extension = ExtensionBuilder()
        .SetManifest(DictionaryBuilder()
                     .Set("name", "No background")
                     .Set("version", "1")
                     .Set("manifest_version", 2))
        .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
        .Build();
    service_->AddExtension(extension);
    return extension;
  }

  // Creates and registers an extension with a lazy background page.
  scoped_refptr<Extension> CreateLazyBackgroundExtension() {
    scoped_refptr<Extension> extension = ExtensionBuilder()
        .SetManifest(DictionaryBuilder()
            .Set("name", "Lazy background")
            .Set("version", "1")
            .Set("manifest_version", 2)
            .Set("background",
                  DictionaryBuilder()
                  .Set("page", "background.html")
                  .SetBoolean("persistent", false)))
        .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
        .Build();
    service_->AddExtension(extension);
    return extension;
  }

 private:
  // The total number of pending tasks that have been executed.
  int task_run_count_;

  DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
};

// Tests that only extensions with background pages should have tasks queued.
TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
  InitializeEmptyExtensionService();
  InitializeProcessManager();

  LazyBackgroundTaskQueue queue(profile_.get());

  // Build a simple extension with no background page.
  scoped_refptr<Extension> no_background = CreateSimpleExtension();
  EXPECT_FALSE(queue.ShouldEnqueueTask(profile_.get(), no_background.get()));

  // Build another extension with a background page.
  scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension();
  EXPECT_TRUE(queue.ShouldEnqueueTask(profile_.get(), with_background.get()));
}

// Tests that adding tasks actually increases the pending task count, and that
// multiple extensions can have pending tasks.
TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
  InitializeEmptyExtensionService();

  // Swap in our stub TestProcessManager.
  TestExtensionSystem* extension_system =
      static_cast<extensions::TestExtensionSystem*>(
          ExtensionSystem::Get(profile_.get()));
  // Owned by |extension_system|.
  TestProcessManager* process_manager = new TestProcessManager(profile_.get());
  extension_system->SetProcessManager(process_manager);

  LazyBackgroundTaskQueue queue(profile_.get());

  // Build a simple extension with no background page.
  scoped_refptr<Extension> no_background = CreateSimpleExtension();

  // Adding a pending task increases the number of extensions with tasks, but
  // doesn't run the task.
  queue.AddPendingTask(profile_.get(),
                       no_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
  EXPECT_EQ(0, task_run_count());

  // Another task on the same extension doesn't increase the number of
  // extensions that have tasks and doesn't run any tasks.
  queue.AddPendingTask(profile_.get(),
                       no_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
  EXPECT_EQ(0, task_run_count());

  // Adding a task on an extension with a lazy background page tries to create
  // a background host, and if that fails, runs the task immediately.
  scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension();
  queue.AddPendingTask(profile_.get(),
                       lazy_background->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(2u, queue.extensions_with_pending_tasks());
  // The process manager tried to create a background host.
  EXPECT_EQ(1, process_manager->create_count());
  // The task ran immediately because the creation failed.
  EXPECT_EQ(1, task_run_count());
}

// Tests that pending tasks are actually run.
TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
  InitializeEmptyExtensionService();

  LazyBackgroundTaskQueue queue(profile_.get());

  // ProcessPendingTasks is a no-op if there are no tasks.
  scoped_refptr<Extension> extension = CreateSimpleExtension();
  queue.ProcessPendingTasks(NULL, profile_.get(), extension);
  EXPECT_EQ(0, task_run_count());

  // Schedule a task to run.
  queue.AddPendingTask(profile_.get(),
                       extension->id(),
                       base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
                                  base::Unretained(this)));
  EXPECT_EQ(0, task_run_count());
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());

  // Trying to run tasks for an unrelated profile should do nothing.
  TestingProfile profile2;
  queue.ProcessPendingTasks(NULL, &profile2, extension);
  EXPECT_EQ(0, task_run_count());
  EXPECT_EQ(1u, queue.extensions_with_pending_tasks());

  // Processing tasks when there is one pending runs the task and removes the
  // extension from the list of extensions with pending tasks.
  queue.ProcessPendingTasks(NULL, profile_.get(), extension);
  EXPECT_EQ(1, task_run_count());
  EXPECT_EQ(0u, queue.extensions_with_pending_tasks());
}

}  // namespace extensions
