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

#include <stddef.h>

#include <limits>
#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/deferred_start_render_host.h"
#include "extensions/browser/extensions_test.h"
#include "extensions/browser/serial_extension_host_queue.h"

namespace extensions {

namespace {

class StubDeferredStartRenderHost : public DeferredStartRenderHost {
 public:
  // Returns true if this host is being observed by |observer|.
  bool IsObservedBy(DeferredStartRenderHostObserver* observer) {
    return observers_.count(observer) > 0;
  }

 private:
  // DeferredStartRenderHost:
  void AddDeferredStartRenderHostObserver(
      DeferredStartRenderHostObserver* observer) override {
    observers_.insert(observer);
  }
  void RemoveDeferredStartRenderHostObserver(
      DeferredStartRenderHostObserver* observer) override {
    observers_.erase(observer);
  }
  void CreateRenderViewNow() override {}

  std::set<DeferredStartRenderHostObserver*> observers_;
};

const size_t g_invalid_size_t = std::numeric_limits<size_t>::max();

}  // namespace

class LoadMonitoringExtensionHostQueueTest : public ExtensionsTest {
 public:
  LoadMonitoringExtensionHostQueueTest()
      : finished_(false),
        // Arbitrary choice of an invalid size_t.
        num_queued_(g_invalid_size_t),
        num_loaded_(g_invalid_size_t),
        max_awaiting_loading_(g_invalid_size_t),
        max_active_loading_(g_invalid_size_t) {}

  void SetUp() override {
    queue_.reset(new LoadMonitoringExtensionHostQueue(
        // Use a SerialExtensionHostQueue because it's simple.
        std::unique_ptr<ExtensionHostQueue>(new SerialExtensionHostQueue()),
        base::TimeDelta(),  // no delay, easier to test
        base::Bind(&LoadMonitoringExtensionHostQueueTest::Finished,
                   base::Unretained(this))));
  }

 protected:
  // Creates a new DeferredStartRenderHost. Ownership is held by this class,
  // not passed to caller.
  StubDeferredStartRenderHost* CreateHost() {
    stubs_.push_back(base::MakeUnique<StubDeferredStartRenderHost>());
    return stubs_.back().get();
  }

  // Our single LoadMonitoringExtensionHostQueue instance.
  LoadMonitoringExtensionHostQueue* queue() { return queue_.get(); }

  // Returns true if the queue has finished monitoring.
  bool finished() const { return finished_; }

  // These are available after the queue has finished (in which case finished()
  // will return true).
  size_t num_queued() { return num_queued_; }
  size_t num_loaded() { return num_loaded_; }
  size_t max_awaiting_loading() { return max_awaiting_loading_; }
  size_t max_active_loading() { return max_active_loading_; }

 private:
  // Callback when queue has finished monitoring.
  void Finished(size_t num_queued,
                size_t num_loaded,
                size_t max_awaiting_loading,
                size_t max_active_loading) {
    CHECK(!finished_);
    finished_ = true;
    num_queued_ = num_queued;
    num_loaded_ = num_loaded;
    max_awaiting_loading_ = max_awaiting_loading;
    max_active_loading_ = max_active_loading;
  }

  content::TestBrowserThreadBundle thread_bundle_;
  std::unique_ptr<LoadMonitoringExtensionHostQueue> queue_;
  std::vector<std::unique_ptr<StubDeferredStartRenderHost>> stubs_;

  // Set after the queue has finished monitoring.
  bool finished_;
  size_t num_queued_;
  size_t num_loaded_;
  size_t max_awaiting_loading_;
  size_t max_active_loading_;
};

// Tests that if monitoring is never started, nor any hosts added, nothing is
// recorded.
TEST_F(LoadMonitoringExtensionHostQueueTest, NeverStarted) {
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(finished());
}

// Tests that if monitoring has started but no hosts added, it's recorded as 0.
TEST_F(LoadMonitoringExtensionHostQueueTest, NoHosts) {
  queue()->StartMonitoring();

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(0u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(0u, max_awaiting_loading());
  EXPECT_EQ(0u, max_active_loading());
}

// Tests that adding a host starts monitoring.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddOneHost) {
  queue()->Add(CreateHost());

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(0u, max_active_loading());
}

// Tests that a host added and removed is still recorded, but not as a load
// finished.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndRemoveOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->Remove(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(0u, max_active_loading());
}

// Tests adding and starting a single host.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndStartOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(1u, max_active_loading());
}

// Tests adding and destroying a single host without starting it.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndDestroyOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDestroyed(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(0u, max_active_loading());
}

// Tests adding, starting, and stopping a single host.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndStartAndStopOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(1u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(1u, max_active_loading());
}

// Tests adding, starting, and stopping a single host - twice.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndStartAndStopOneHostTwice) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host);

  // Re-starting loading should also be recorded fine (e.g. navigations could
  // trigger this).
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(2u, num_loaded());  // 2 loaded this time, because we ran twice
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(1u, max_active_loading());
}

// Tests adding, starting, and destroying (i.e. an implicit stop) a single host.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndStartAndDestroyOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);
  queue()->OnDeferredStartRenderHostDestroyed(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(1u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(1u, max_active_loading());
}

// Tests adding, starting, and removing a single host.
TEST_F(LoadMonitoringExtensionHostQueueTest, AddAndStartAndRemoveOneHost) {
  DeferredStartRenderHost* host = CreateHost();
  queue()->Add(host);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host);
  queue()->Remove(host);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(1u, num_queued());
  EXPECT_EQ(0u, num_loaded());
  EXPECT_EQ(1u, max_awaiting_loading());
  EXPECT_EQ(1u, max_active_loading());
}

// Tests monitoring a sequence of hosts.
TEST_F(LoadMonitoringExtensionHostQueueTest, Sequence) {
  // Scenario:
  //
  // 6 hosts will be added, only 5 will start loading, with a maximum of 4 in
  // the queue and 3 loading at any time. Only 2 will finish.
  DeferredStartRenderHost* host1 = CreateHost();
  DeferredStartRenderHost* host2 = CreateHost();
  DeferredStartRenderHost* host3 = CreateHost();
  DeferredStartRenderHost* host4 = CreateHost();
  DeferredStartRenderHost* host5 = CreateHost();
  DeferredStartRenderHost* host6 = CreateHost();

  queue()->Add(host1);
  queue()->Add(host2);
  queue()->Add(host3);

  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host1);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host2);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host1);

  queue()->Add(host4);
  queue()->Add(host5);
  queue()->Add(host6);

  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host3);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host4);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host4);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host5);

  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(finished());
  EXPECT_EQ(6u, num_queued());
  EXPECT_EQ(2u, num_loaded());
  EXPECT_EQ(4u, max_awaiting_loading());
  EXPECT_EQ(3u, max_active_loading());

  // Complete a realistic sequence by stopping and/or destroying all hosts.
  queue()->OnDeferredStartRenderHostDestroyed(host1);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host2);
  queue()->OnDeferredStartRenderHostDestroyed(host2);
  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host3);
  queue()->OnDeferredStartRenderHostDestroyed(host3);
  queue()->OnDeferredStartRenderHostDestroyed(host4);
  queue()->OnDeferredStartRenderHostDestroyed(host5);  // never stopped
  queue()->OnDeferredStartRenderHostDestroyed(host6);  // never started/stopped
}

// Tests that the queue is observing Hosts from adding them through to being
// removed - that the load sequence itself is irrelevant.
//
// This is an unfortunate implementation-style test, but it used to be a bug
// and difficult to catch outside of a proper test framework - one in which we
// don't have to trigger events by hand.
TEST_F(LoadMonitoringExtensionHostQueueTest, ObserverLifetime) {
  StubDeferredStartRenderHost* host1 = CreateHost();
  StubDeferredStartRenderHost* host2 = CreateHost();
  StubDeferredStartRenderHost* host3 = CreateHost();
  StubDeferredStartRenderHost* host4 = CreateHost();

  EXPECT_FALSE(host1->IsObservedBy(queue()));
  EXPECT_FALSE(host2->IsObservedBy(queue()));
  EXPECT_FALSE(host3->IsObservedBy(queue()));
  EXPECT_FALSE(host4->IsObservedBy(queue()));

  queue()->Add(host1);
  queue()->Add(host2);
  queue()->Add(host3);
  queue()->Add(host4);

  EXPECT_TRUE(host1->IsObservedBy(queue()));
  EXPECT_TRUE(host2->IsObservedBy(queue()));
  EXPECT_TRUE(host3->IsObservedBy(queue()));
  EXPECT_TRUE(host4->IsObservedBy(queue()));

  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host1);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host2);
  queue()->OnDeferredStartRenderHostDidStartFirstLoad(host3);
  // host4 will test that we Remove before Starting - so don't start.

  EXPECT_TRUE(host1->IsObservedBy(queue()));
  EXPECT_TRUE(host2->IsObservedBy(queue()));
  EXPECT_TRUE(host3->IsObservedBy(queue()));
  EXPECT_TRUE(host4->IsObservedBy(queue()));

  queue()->OnDeferredStartRenderHostDidStopFirstLoad(host1);
  queue()->OnDeferredStartRenderHostDestroyed(host2);

  EXPECT_TRUE(host1->IsObservedBy(queue()));
  EXPECT_TRUE(host2->IsObservedBy(queue()));

  queue()->Remove(host1);
  queue()->Remove(host2);
  queue()->Remove(host3);
  queue()->Remove(host4);

  EXPECT_FALSE(host1->IsObservedBy(queue()));
  EXPECT_FALSE(host2->IsObservedBy(queue()));
  EXPECT_FALSE(host3->IsObservedBy(queue()));
  EXPECT_FALSE(host4->IsObservedBy(queue()));
}

}  // namespace extensions
