// Copyright (c) 2015 The Chromium Embedded Framework 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 <vector>

#include "include/base/cef_bind.h"
#include "include/cef_file_util.h"
#include "include/cef_waitable_event.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_resource_manager.h"
#include "include/wrapper/cef_scoped_temp_dir.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/ceftests/routing_test_handler.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/shared/browser/file_util.h"

namespace {

std::string CreateMessage(const std::string& name, const std::string& value) {
  return name + ":" + value;
}

// The returned contents execute a JavaScript callback containing |message|.
std::string CreateContents(const std::string& message) {
  return "<html><body>" + message +
         "<script>"
         "window.testQuery({request:'" +
         message +
         "'});"
         "</script></html></body>";
}

void WriteFile(const std::string& path, const std::string& contents) {
  int contents_size = static_cast<int>(contents.size());
  int write_ct =
      client::file_util::WriteFile(path, contents.data(), contents_size);
  EXPECT_EQ(contents_size, write_ct);
}

CefRefPtr<CefResourceHandler> CreateContentsResourceHandler(
    const std::string& message) {
  const std::string& contents = CreateContents(message);
  CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
      static_cast<void*>(const_cast<char*>(contents.data())),
      contents.length());
  return new CefStreamResourceHandler("text/html", stream);
}

const char kDoneMsg[] = "ResourceManagerTestHandler.Done";
const char kNotHandled[] = "NotHandled";

// Browser side.
class ResourceManagerTestHandler : public RoutingTestHandler {
 public:
  struct State {
    State() : manager_(new CefResourceManager()), expected_message_ct_(0) {}

    CefRefPtr<CefResourceManager> manager_;

    // Set of URLs that will be loaded.
    std::vector<std::string> urls_;

    // Set of messages that were received.
    std::vector<std::string> messages_;

    // If non-zero the test will not complete until the expected number of
    // messages have been received.
    size_t expected_message_ct_;
  };

  explicit ResourceManagerTestHandler(State* state)
      : state_(state), current_url_(0) {
    EXPECT_TRUE(state_);
    EXPECT_TRUE(state_->manager_.get());
    EXPECT_TRUE(!state_->urls_.empty());
    EXPECT_TRUE(state_->messages_.empty());
  }

  void RunTest() override {
    // Create the browser.
    CreateBrowser(GetNextURL());

    SetTestTimeout();
  }

  cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback) override {
    return state_->manager_->OnBeforeResourceLoad(browser, frame, request,
                                                  callback);
  }

  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override {
    // The ProviderDoNothing test destroys the manager before the handler.
    if (state_->manager_) {
      CefRefPtr<CefResourceHandler> handler =
          state_->manager_->GetResourceHandler(browser, frame, request);
      if (handler.get())
        return handler;
    }

    return CreateContentsResourceHandler(CreateMessage(kDoneMsg, kNotHandled));
  }

  bool OnQuery(CefRefPtr<CefBrowser> browser,
               CefRefPtr<CefFrame> frame,
               int64 query_id,
               const CefString& request,
               bool persistent,
               CefRefPtr<Callback> callback) override {
    state_->messages_.push_back(request);
    callback->Success("");

    CefPostTask(TID_UI, base::Bind(&ResourceManagerTestHandler::Continue, this,
                                   browser));

    return true;
  }

  // Wait a bit before destroying the test. Used with ProviderDoNothing.
  void DelayedDestroyTest() {
    CefPostDelayedTask(
        TID_UI, base::Bind(&ResourceManagerTestHandler::DestroyTest, this),
        100);
  }

 private:
  void Continue(CefRefPtr<CefBrowser> browser) {
    if (state_->expected_message_ct_ == 0) {
      // Load each URL sequentially.
      const std::string& next_url = GetNextURL();
      if (next_url.empty())
        DestroyTest();
      else
        browser->GetMainFrame()->LoadURL(next_url);
    } else if (state_->messages_.size() == state_->expected_message_ct_) {
      DestroyTest();
    }
  }

  std::string GetNextURL() {
    if (current_url_ >= state_->urls_.size())
      return std::string();
    return state_->urls_[current_url_++];
  }

  State* state_;
  size_t current_url_;

  IMPLEMENT_REFCOUNTING(ResourceManagerTestHandler);
};

}  // namespace

// Test with no providers.
TEST(ResourceManagerTest, NoProviders) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Should get the message returned from GetResourceHandler when the request is
  // not handled.
  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

namespace {

// Content provider that tracks execution state.
class TestProvider : public CefResourceManager::Provider {
 public:
  struct State {
    TrackCallback got_on_request_;
    TrackCallback got_on_request_canceled_;
    TrackCallback got_destruct_;
    base::Closure destruct_callback_;
    std::string request_url_;
  };

  explicit TestProvider(State* state) : state_(state) { EXPECT_TRUE(state_); }

  ~TestProvider() {
    CEF_REQUIRE_IO_THREAD();
    state_->got_destruct_.yes();
    if (!state_->destruct_callback_.is_null())
      state_->destruct_callback_.Run();
  }

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    CEF_REQUIRE_IO_THREAD();
    EXPECT_FALSE(state_->got_on_request_);
    EXPECT_FALSE(state_->got_on_request_canceled_);

    state_->got_on_request_.yes();
    state_->request_url_ = request->url();

    return false;
  }

  void OnRequestCanceled(
      scoped_refptr<CefResourceManager::Request> request) override {
    CEF_REQUIRE_IO_THREAD();
    EXPECT_TRUE(state_->got_on_request_);
    EXPECT_FALSE(state_->got_on_request_canceled_);

    state_->got_on_request_canceled_.yes();
    EXPECT_STREQ(state_->request_url_.c_str(), request->url().c_str());
  }

 private:
  State* state_;

  DISALLOW_COPY_AND_ASSIGN(TestProvider);
};

// Helper that blocks on destruction of 1 or more TestProviders.
class ProviderDestructHelper {
 public:
  explicit ProviderDestructHelper(int expected_count) : current_count_(0) {
    event_ = CefWaitableEvent::CreateWaitableEvent(true, false);
    callback_ =
        base::Bind(&DestructCallback, expected_count, &current_count_, event_);
  }

  const base::Closure& callback() const { return callback_; }

  void Wait() { event_->Wait(); }

 private:
  static void DestructCallback(int expected_count,
                               int* current_count,
                               CefRefPtr<CefWaitableEvent> event) {
    if (++(*current_count) == expected_count)
      event->Signal();
  }

  int current_count_;
  CefRefPtr<CefWaitableEvent> event_;
  base::Closure callback_;
};

// Test that that the URL retrieved via Request::url() is parsed as expected.
// Fragment or query components in any order should be removed.
void TestUrlParsing(const char* kUrl) {
  const char kRequestUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state;

  ProviderDestructHelper destruct_helper(1);
  provider_state.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(new TestProvider(&provider_state), 0,
                              std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // The provider is called.
  EXPECT_TRUE(provider_state.got_on_request_);
  EXPECT_FALSE(provider_state.got_on_request_canceled_);
  EXPECT_TRUE(provider_state.got_destruct_);

  // The expected URL is received.
  EXPECT_STREQ(kRequestUrl, provider_state.request_url_.c_str());

  // The request is not handled.
  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

}  // namespace

TEST(ResourceManagerTest, UrlParsingNoQueryOrFragment) {
  TestUrlParsing("http://test.com/ResourceManagerTest");
}

TEST(ResourceManagerTest, UrlParsingWithQuery) {
  TestUrlParsing("http://test.com/ResourceManagerTest?foo=bar&choo=too");
}

TEST(ResourceManagerTest, UrlParsingWithFragment) {
  TestUrlParsing("http://test.com/ResourceManagerTest#some/fragment");
}

TEST(ResourceManagerTest, UrlParsingWithQueryAndFragment) {
  TestUrlParsing("http://test.com/ResourceManagerTest?foo=bar#some/fragment");
}

TEST(ResourceManagerTest, UrlParsingWithFragmentAndQuery) {
  TestUrlParsing("http://test.com/ResourceManagerTest#some/fragment?foo=bar");
}

namespace {

const char kProviderId[] = "provider";

// Content provider that performs simple tests.
class SimpleTestProvider : public TestProvider {
 public:
  enum Mode {
    NOT_HANDLED,
    CONTINUE,
    STOP,
    REMOVE,
    REMOVE_ALL,
    DO_NOTHING,
  };

  SimpleTestProvider(State* state, Mode mode, CefResourceManager* manager)
      : TestProvider(state), mode_(mode), manager_(manager) {}

  SimpleTestProvider(State* state,
                     Mode mode,
                     CefResourceManager* manager,
                     base::Closure do_nothing_callback)
      : TestProvider(state),
        mode_(mode),
        manager_(manager),
        do_nothing_callback_(do_nothing_callback) {}

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    TestProvider::OnRequest(request);

    if (mode_ == NOT_HANDLED)
      return false;
    else if (mode_ == CONTINUE)
      request->Continue(nullptr);
    else if (mode_ == STOP)
      request->Stop();
    else if (mode_ == REMOVE)
      manager_->RemoveProviders(kProviderId);
    else if (mode_ == REMOVE_ALL)
      manager_->RemoveAllProviders();
    else if (mode_ == DO_NOTHING) {
      EXPECT_FALSE(do_nothing_callback_.is_null());
      do_nothing_callback_.Run();
      do_nothing_callback_.Reset();
    }

    return true;
  }

 private:
  Mode mode_;
  CefResourceManager* manager_;  // Weak reference.
  base::Closure do_nothing_callback_;

  DISALLOW_COPY_AND_ASSIGN(SimpleTestProvider);
};

}  // namespace

// Test with multiple providers that do not handle the request.
TEST(ResourceManagerTest, ProviderNotHandled) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state1, SimpleTestProvider::NOT_HANDLED,
                             nullptr),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::NOT_HANDLED,
                             nullptr),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test with multiple providers that all continue.
TEST(ResourceManagerTest, ProviderContinue) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state1, SimpleTestProvider::CONTINUE,
                             nullptr),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
                             nullptr),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test with multiple providers where the first one stops.
TEST(ResourceManagerTest, ProviderStop) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state1, SimpleTestProvider::STOP,
                             nullptr),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
                             nullptr),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // 1st provider is called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  // 2nd provider is not called because the 1st provider stopped.
  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test with multiple providers where the first one removes multiple providers
// including itself.
TEST(ResourceManagerTest, ProviderRemove) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;

  ProviderDestructHelper destruct_helper(3);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state1, SimpleTestProvider::REMOVE,
                             state.manager_.get()),
      0, kProviderId);
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
                             nullptr),
      0, kProviderId);
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state3, SimpleTestProvider::CONTINUE,
                             nullptr),
      1, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // 1st provider is called and canceled.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_TRUE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  // 2nd provider is removed with the 1st provider due to sharing the same
  // identifier.
  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  // 3rd provider is called.
  EXPECT_TRUE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test with multiple providers where the first provider removes all.
TEST(ResourceManagerTest, ProviderRemoveAll) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;

  ProviderDestructHelper destruct_helper(3);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state1, SimpleTestProvider::REMOVE_ALL,
                             state.manager_.get()),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
                             nullptr),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state3, SimpleTestProvider::CONTINUE,
                             nullptr),
      1, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // 1st provider is called and canceled.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_TRUE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  // 2nd and 3rd providers are not called due to removal.
  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_FALSE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test with multiple providers that do not continue and will be destroyed when
// the manager is destroyed.
TEST(ResourceManagerTest, ProviderDoNothing) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);

  // DelayedDestroyTest will be executed from SimpleTestHandler::OnRequest.
  state.manager_->AddProvider(
      new SimpleTestProvider(
          &provider_state1, SimpleTestProvider::DO_NOTHING, nullptr,
          base::Bind(&ResourceManagerTestHandler::DelayedDestroyTest, handler)),
      0, std::string());
  state.manager_->AddProvider(
      new SimpleTestProvider(&provider_state2, SimpleTestProvider::DO_NOTHING,
                             nullptr),
      0, std::string());

  handler->ExecuteTest();

  // Destroy the resource manager before the handler so that pending requests
  // are canceled. ResourceManagerTestHandler::GetResourceHandler will be called
  // after the manager is destroyed.
  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  ReleaseAndWaitForDestructor(handler);

  // Only the first provider is called. It will be canceled when the manager is
  // destroyed.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_TRUE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  // Nothing completed.
  EXPECT_EQ(state.messages_.size(), 0U);
}

// Test AddContentProvider.
TEST(ResourceManagerTest, ContentProvider) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);

  // Only the first 2 URLs will be handled.
  state.manager_->AddContentProvider(kUrl1, CreateContents(success1_message),
                                     "text/html", 0, std::string());
  state.manager_->AddContentProvider(kUrl2, CreateContents(success2_message),
                                     "text/html", 0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  WaitForIOThread();

  // Both providers are called and return the expected results.
  EXPECT_EQ(state.messages_.size(), 3U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(success2_message, state.messages_[1]);
  EXPECT_EQ(not_handled_message, state.messages_[2]);
}

// Test AddDirectoryProvider.
TEST(ResourceManagerTest, DirectoryProvider) {
  const char kUrlBase[] = "http://test.com/ResourceManager";
  const char kFile1[] = "File1.html";
  const char kFile2[] = "File2.html";
  const char kFile3[] = "File3.html";
  const char kFile4[] = "File4.html";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrlBase + std::string("/") + kFile1);
  state.urls_.push_back(kUrlBase + std::string("/") + kFile2);
  state.urls_.push_back(kUrlBase + std::string("/sub/") + kFile3);
  state.urls_.push_back(kUrlBase + std::string("/") + kFile4);

  CefScopedTempDir scoped_dir;
  EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());

  // Write the files to disk.
  const std::string& temp_dir = scoped_dir.GetPath();
  WriteFile(client::file_util::JoinPath(temp_dir, kFile1),
            CreateContents(success1_message));
  WriteFile(client::file_util::JoinPath(temp_dir, kFile2),
            CreateContents(success2_message));

  // Also include a subdirectory.
  const std::string& sub_dir = client::file_util::JoinPath(temp_dir, "sub");
  EXPECT_TRUE(CefCreateDirectory(sub_dir));
  WriteFile(client::file_util::JoinPath(sub_dir, kFile3),
            CreateContents(success3_message));

  state.manager_->AddDirectoryProvider(kUrlBase, temp_dir, 0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  WaitForIOThread();

  EXPECT_TRUE(scoped_dir.Delete());

  // The first 3 URLs are handled.
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(success2_message, state.messages_[1]);
  EXPECT_EQ(success3_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);
}

// Test AddArchiveProvider.
TEST(ResourceManagerTest, ArchiveProvider) {
  const char kUrlBase[] = "http://test.com/ResourceManager";
  const char kFile1[] = "File1.html";
  const char kFile2[] = "File2.html";
  const char kFile3[] = "File3.html";
  const char kFile4[] = "File4.html";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrlBase + std::string("/") + kFile1);
  state.urls_.push_back(kUrlBase + std::string("/") + kFile2);
  state.urls_.push_back(kUrlBase + std::string("/sub/") + kFile3);
  state.urls_.push_back(kUrlBase + std::string("/") + kFile4);

  // Only the first 2 URLs will be handled.
  CefScopedTempDir scoped_dir;
  EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());

  const std::string& temp_dir = scoped_dir.GetPath();

  // Write the files to disk.
  const std::string& file_dir = client::file_util::JoinPath(temp_dir, "files");
  EXPECT_TRUE(CefCreateDirectory(file_dir));
  WriteFile(client::file_util::JoinPath(file_dir, kFile1),
            CreateContents(success1_message));
  WriteFile(client::file_util::JoinPath(file_dir, kFile2),
            CreateContents(success2_message));

  // Also include a subdirectory.
  const std::string& sub_dir = client::file_util::JoinPath(file_dir, "sub");
  EXPECT_TRUE(CefCreateDirectory(sub_dir));
  WriteFile(client::file_util::JoinPath(sub_dir, kFile3),
            CreateContents(success3_message));

  const std::string& archive_path =
      client::file_util::JoinPath(temp_dir, "archive.zip");

  // Create the archive file.
  EXPECT_TRUE(CefZipDirectory(file_dir, archive_path, false));

  state.manager_->AddArchiveProvider(kUrlBase, archive_path, std::string(), 0,
                                     std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  WaitForIOThread();

  EXPECT_TRUE(scoped_dir.Delete());

  // The first 3 URLs are handled.
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(success2_message, state.messages_[1]);
  EXPECT_EQ(success3_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);
}

namespace {

// Content provider that only handles a single request.
class OneShotProvider : public CefResourceManager::Provider {
 public:
  OneShotProvider(const std::string& content,
                  const base::Closure& destruct_callback)
      : done_(false), content_(content), destruct_callback_(destruct_callback) {
    EXPECT_FALSE(content.empty());
  }

  ~OneShotProvider() {
    CEF_REQUIRE_IO_THREAD();
    destruct_callback_.Run();
  }

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    CEF_REQUIRE_IO_THREAD();

    if (done_) {
      // Provider only handles a single request.
      return false;
    }

    done_ = true;

    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        static_cast<void*>(const_cast<char*>(content_.data())),
        content_.length());

    request->Continue(new CefStreamResourceHandler("text/html", stream));
    return true;
  }

 private:
  bool done_;
  std::string content_;
  base::Closure destruct_callback_;

  DISALLOW_COPY_AND_ASSIGN(OneShotProvider);
};

}  // namespace

// Test that providers are called in the expected order and return expected
// results.
TEST(ResourceManagerTest, ProviderOrder) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";
  const char kUrl4[] = "http://test.com/ResourceManagerTest4";
  const char kUrl5[] = "http://test.com/ResourceManagerTest5";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);
  state.urls_.push_back(kUrl4);
  state.urls_.push_back(kUrl5);

  ProviderDestructHelper destruct_helper(4);

  // Resulting order should be sequential; success1 .. success4.
  state.manager_->AddProvider(
      new OneShotProvider(CreateContents(success2_message),
                          destruct_helper.callback()),
      0, std::string());
  state.manager_->AddProvider(
      new OneShotProvider(CreateContents(success1_message),
                          destruct_helper.callback()),
      -100, std::string());
  state.manager_->AddProvider(
      new OneShotProvider(CreateContents(success4_message),
                          destruct_helper.callback()),
      100, std::string());
  state.manager_->AddProvider(
      new OneShotProvider(CreateContents(success3_message),
                          destruct_helper.callback()),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  EXPECT_EQ(state.messages_.size(), 5U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(success2_message, state.messages_[1]);
  EXPECT_EQ(success3_message, state.messages_[2]);
  EXPECT_EQ(success4_message, state.messages_[3]);
  EXPECT_EQ(not_handled_message, state.messages_[4]);
}

namespace {

// Content provider that returns the path component as the result.
class EchoProvider : public CefResourceManager::Provider {
 public:
  EchoProvider(const std::string& base_url) : base_url_(base_url) {
    EXPECT_TRUE(!base_url_.empty());
  }

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    CEF_REQUIRE_IO_THREAD();

    const std::string& url = request->url();
    if (url.find(base_url_) != 0U) {
      // Not handled by this provider.
      return false;
    }

    const std::string& content = CreateContents(url);

    // Parse the URL to identify the delay.
    int delay = atoi(url.substr(base_url_.size()).data());
    EXPECT_GE(delay, 0);

    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        static_cast<void*>(const_cast<char*>(content.data())),
        content.length());

    CefPostDelayedTask(
        TID_IO,
        base::Bind(&CefResourceManager::Request::Continue, request,
                   new CefStreamResourceHandler("text/html", stream)),
        delay);

    return true;
  }

 private:
  std::string base_url_;

  DISALLOW_COPY_AND_ASSIGN(EchoProvider);
};

}  // namespace

// Test that many requests pending at the same time complete in the expected
// order and return correct results.
TEST(ResourceManagerTest, ManyRequests) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";
  const char kBaseUrl[] = "http://test.com/ResourceManagerSubTest/";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  state.expected_message_ct_ = 50U;

  // Build a page with lots of iframes.
  std::stringstream ss;
  ss << "<html><body>";
  for (size_t i = 0U; i < state.expected_message_ct_; ++i) {
    ss << "<iframe src=\"" << kBaseUrl << (i * 10) << "\"></iframe>";
  }
  ss << "</body></html>";

  state.manager_->AddContentProvider(kUrl, ss.str(), "text/html", 0,
                                     std::string());
  state.manager_->AddProvider(new EchoProvider(kBaseUrl), 0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  WaitForIOThread();

  EXPECT_EQ(state.messages_.size(), state.expected_message_ct_);

  // Requests should complete in order due to the delay.
  for (size_t i = 0; i < state.messages_.size(); ++i) {
    ss.str("");
    ss << kBaseUrl << (i * 10);
    EXPECT_EQ(ss.str(), state.messages_[i]);
  }
}

namespace {

// Content provider that only handles a single request and then removes itself
// from the manager.
class OneShotRemovalProvider : public TestProvider {
 public:
  OneShotRemovalProvider(State* state,
                         const std::string& content,
                         CefResourceManager* manager,
                         const std::string& identifier,
                         bool remove_before_continue)
      : TestProvider(state),
        content_(content),
        manager_(manager),
        identifier_(identifier),
        remove_before_continue_(remove_before_continue) {
    EXPECT_FALSE(content.empty());
  }

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    TestProvider::OnRequest(request);

    CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
        static_cast<void*>(const_cast<char*>(content_.data())),
        content_.length());

    if (remove_before_continue_) {
      // Removing the provider before continuing should trigger a call to
      // OnRequestCanceled.
      if (identifier_.empty())
        manager_->RemoveAllProviders();
      else
        manager_->RemoveProviders(identifier_);
    }

    request->Continue(new CefStreamResourceHandler("text/html", stream));

    if (!remove_before_continue_) {
      // The request has already completed so OnRequestCanceled is not called.
      if (identifier_.empty())
        manager_->RemoveAllProviders();
      else
        manager_->RemoveProviders(identifier_);
    }

    return true;
  }

 private:
  std::string content_;
  CefResourceManager* manager_;  // Weak reference.
  std::string identifier_;
  bool remove_before_continue_;

  DISALLOW_COPY_AND_ASSIGN(OneShotRemovalProvider);
};

}  // namespace

// Test that removal of the current provider after continue has the expected
// results.
TEST(ResourceManagerTest, RemoveProviderAfterContinue) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";
  const char kUrl4[] = "http://test.com/ResourceManagerTest4";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);
  state.urls_.push_back(kUrl4);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;
  TestProvider::State provider_state4;

  ProviderDestructHelper destruct_helper(4);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();
  provider_state4.destruct_callback_ = destruct_helper.callback();

  const char kIdentifier1[] = "id1";
  const char kIdentifier2[] = "id2";
  const char kIdentifier4[] = "id4";

  // Resulting order should be sequential; success1 .. success4.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state2,
                                 CreateContents(success2_message),
                                 state.manager_.get(), kIdentifier2, false),
      0, kIdentifier2);
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state1,
                                 CreateContents(success1_message),
                                 state.manager_.get(), kIdentifier1, false),
      -100, kIdentifier1);
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state4,
                                 CreateContents(success4_message),
                                 state.manager_.get(), kIdentifier4, false),
      100, kIdentifier4);
  // Will be removed at the same time as #2 and therefore never called.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state3,
                                 CreateContents(success3_message),
                                 state.manager_.get(), kIdentifier2, false),
      0, kIdentifier2);

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers except for 3 (which is removed at the same time as 2 and
  // therefore never executed) should complete.
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(success2_message, state.messages_[1]);
  EXPECT_EQ(success4_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);

  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  // Removed at the same time as 2 and therefore not executed.
  EXPECT_FALSE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_TRUE(provider_state4.got_on_request_);
  EXPECT_FALSE(provider_state4.got_on_request_canceled_);
  EXPECT_TRUE(provider_state4.got_destruct_);
}

// Test that removal of the current provider before continue has the expected
// results.
TEST(ResourceManagerTest, RemoveProviderBeforeContinue) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";
  const char kUrl4[] = "http://test.com/ResourceManagerTest4";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);
  state.urls_.push_back(kUrl4);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;
  TestProvider::State provider_state4;

  ProviderDestructHelper destruct_helper(4);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();
  provider_state4.destruct_callback_ = destruct_helper.callback();

  const char kIdentifier1[] = "id1";
  const char kIdentifier2[] = "id2";
  const char kIdentifier4[] = "id4";

  // Resulting order should be sequential; success1 .. success4.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state2,
                                 CreateContents(success2_message),
                                 state.manager_.get(), kIdentifier2, true),
      0, kIdentifier2);
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state1,
                                 CreateContents(success1_message),
                                 state.manager_.get(), kIdentifier1, true),
      -100, kIdentifier1);
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state4,
                                 CreateContents(success4_message),
                                 state.manager_.get(), kIdentifier4, true),
      100, kIdentifier4);
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state3,
                                 CreateContents(success3_message),
                                 state.manager_.get(), kIdentifier2, true),
      0, kIdentifier2);

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // No providers should complete.
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(not_handled_message, state.messages_[0]);
  EXPECT_EQ(not_handled_message, state.messages_[1]);
  EXPECT_EQ(not_handled_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);

  // All providers except 3 should be called and then canceled.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_TRUE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_TRUE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  // Removed at the same time as 2 and therefore not executed.
  EXPECT_FALSE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_TRUE(provider_state4.got_on_request_);
  EXPECT_TRUE(provider_state4.got_on_request_canceled_);
  EXPECT_TRUE(provider_state4.got_destruct_);
}

// Test that removal of all providers after continue has the expected results.
TEST(ResourceManagerTest, RemoveAllProvidersAfterContinue) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";
  const char kUrl4[] = "http://test.com/ResourceManagerTest4";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);
  state.urls_.push_back(kUrl4);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;
  TestProvider::State provider_state4;

  ProviderDestructHelper destruct_helper(4);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();
  provider_state4.destruct_callback_ = destruct_helper.callback();

  // Resulting order should be sequential; success1 .. success4.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state2,
                                 CreateContents(success2_message),
                                 state.manager_.get(), std::string(), false),
      0, std::string());
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state1,
                                 CreateContents(success1_message),
                                 state.manager_.get(), std::string(), false),
      -100, std::string());
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state4,
                                 CreateContents(success4_message),
                                 state.manager_.get(), std::string(), false),
      100, std::string());
  // Will be removed at the same time as #2 and therefore never called.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state3,
                                 CreateContents(success3_message),
                                 state.manager_.get(), std::string(), false),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // Only the 1st provider should complete
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(success1_message, state.messages_[0]);
  EXPECT_EQ(not_handled_message, state.messages_[1]);
  EXPECT_EQ(not_handled_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);

  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_FALSE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_FALSE(provider_state4.got_on_request_);
  EXPECT_FALSE(provider_state4.got_on_request_canceled_);
  EXPECT_TRUE(provider_state4.got_destruct_);
}

// Test that removal of all providers before continue has the expected results.
TEST(ResourceManagerTest, RemoveAllProvidersBeforeContinue) {
  const char kUrl1[] = "http://test.com/ResourceManagerTest1";
  const char kUrl2[] = "http://test.com/ResourceManagerTest2";
  const char kUrl3[] = "http://test.com/ResourceManagerTest3";
  const char kUrl4[] = "http://test.com/ResourceManagerTest4";

  const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
  const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
  const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
  const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
  const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl1);
  state.urls_.push_back(kUrl2);
  state.urls_.push_back(kUrl3);
  state.urls_.push_back(kUrl4);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;
  TestProvider::State provider_state3;
  TestProvider::State provider_state4;

  ProviderDestructHelper destruct_helper(4);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();
  provider_state3.destruct_callback_ = destruct_helper.callback();
  provider_state4.destruct_callback_ = destruct_helper.callback();

  // Resulting order should be sequential; success1 .. success4.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state2,
                                 CreateContents(success2_message),
                                 state.manager_.get(), std::string(), true),
      0, std::string());
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state1,
                                 CreateContents(success1_message),
                                 state.manager_.get(), std::string(), true),
      -100, std::string());
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state4,
                                 CreateContents(success4_message),
                                 state.manager_.get(), std::string(), true),
      100, std::string());
  // Will be removed at the same time as #2 and therefore never called.
  state.manager_->AddProvider(
      new OneShotRemovalProvider(&provider_state3,
                                 CreateContents(success3_message),
                                 state.manager_.get(), std::string(), true),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // No providers should complete.
  EXPECT_EQ(state.messages_.size(), 4U);
  EXPECT_EQ(not_handled_message, state.messages_[0]);
  EXPECT_EQ(not_handled_message, state.messages_[1]);
  EXPECT_EQ(not_handled_message, state.messages_[2]);
  EXPECT_EQ(not_handled_message, state.messages_[3]);

  // 1st provider should also be canceled.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_TRUE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_FALSE(provider_state3.got_on_request_);
  EXPECT_FALSE(provider_state3.got_on_request_canceled_);
  EXPECT_TRUE(provider_state3.got_destruct_);

  EXPECT_FALSE(provider_state4.got_on_request_);
  EXPECT_FALSE(provider_state4.got_on_request_canceled_);
  EXPECT_TRUE(provider_state4.got_destruct_);
}

namespace {

// Test the URL filter capability.
class UrlFilterTestProvider : public TestProvider {
 public:
  UrlFilterTestProvider(State* state,
                        const std::string& expected_url,
                        const std::string& expected_url_after_filter)
      : TestProvider(state),
        expected_url_(expected_url),
        expected_url_after_filter_(expected_url_after_filter) {}

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    TestProvider::OnRequest(request);

    // Request::url is already filtered.
    EXPECT_EQ(expected_url_, request->url());

    // Explicitly filter the URL again.
    const std::string& filtered_url =
        request->url_filter().Run(request->request()->GetURL());
    EXPECT_EQ(expected_url_after_filter_, filtered_url);

    request->Continue(nullptr);
    return true;
  }

 private:
  std::string expected_url_;
  std::string expected_url_after_filter_;
  DISALLOW_COPY_AND_ASSIGN(UrlFilterTestProvider);
};

std::string TestUrlFilter(const std::string& url) {
  return url + "Rewrite";
}

// Add to the URL but keep the query component.
std::string TestUrlFilterWithQuery(const std::string& url) {
  size_t pos = url.find('?');
  if (pos == std::string::npos)
    return url;
  return url.substr(0, pos) + "Rewrite" + url.substr(pos);
}

// Add to the URL but keep the fragment component.
std::string TestUrlFilterWithFragment(const std::string& url) {
  size_t pos = url.find('#');
  if (pos == std::string::npos)
    return url;
  return url.substr(0, pos) + "Rewrite" + url.substr(pos);
}

}  // namespace

// Test the URL filter capability.
TEST(ResourceManagerTest, UrlFilter) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";
  const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  // Set the URL filter.
  state.manager_->SetUrlFilter(base::Bind(TestUrlFilter));

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state1, kExpectedUrl, kExpectedUrl),
      0, std::string());
  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state2, kExpectedUrl, kExpectedUrl),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test the URL filter capability with a query component.
TEST(ResourceManagerTest, UrlFilterWithQuery) {
  const char kUrl[] = "http://test.com/ResourceManagerTest?foo=bar";
  const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";
  const char kExpectedUrlAfterFilter[] =
      "http://test.com/ResourceManagerTestRewrite?foo=bar";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  // Set the URL filter.
  state.manager_->SetUrlFilter(base::Bind(TestUrlFilterWithQuery));

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state1, kExpectedUrl,
                                kExpectedUrlAfterFilter),
      0, std::string());
  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state2, kExpectedUrl,
                                kExpectedUrlAfterFilter),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test the URL filter capability with a fragment component.
TEST(ResourceManagerTest, UrlFilterWithFragment) {
  // Fragment components will not be passed with the request.
  const char kUrl[] = "http://test.com/ResourceManagerTest#fragment";
  const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";
  const char kExpectedUrlAfterFilter[] =
      "http://test.com/ResourceManagerTestRewrite#fragment";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  // Set the URL filter.
  state.manager_->SetUrlFilter(base::Bind(TestUrlFilterWithFragment));

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state1, kExpectedUrl,
                                kExpectedUrlAfterFilter),
      0, std::string());
  state.manager_->AddProvider(
      new UrlFilterTestProvider(&provider_state2, kExpectedUrl,
                                kExpectedUrlAfterFilter),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

namespace {

// Test the mime type resolver capability.
class MimeTypeTestProvider : public TestProvider {
 public:
  MimeTypeTestProvider(State* state, const std::string& expected_mime_type)
      : TestProvider(state), expected_mime_type_(expected_mime_type) {}

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    TestProvider::OnRequest(request);

    const std::string& mime_type =
        request->mime_type_resolver().Run(request->url());
    EXPECT_EQ(expected_mime_type_, mime_type);

    request->Continue(nullptr);
    return true;
  }

 private:
  std::string expected_mime_type_;
  DISALLOW_COPY_AND_ASSIGN(MimeTypeTestProvider);
};

const char kExpectedMimeType[] = "foo/bar";

std::string TestMimeTypeResolver(const std::string& url) {
  return kExpectedMimeType;
}

}  // namespace

// Test the mime type resolver capability.
TEST(ResourceManagerTest, MimeTypeResolver) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  // Set the mime type resolver.
  state.manager_->SetMimeTypeResolver(base::Bind(TestMimeTypeResolver));

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new MimeTypeTestProvider(&provider_state1, kExpectedMimeType), 0,
      std::string());
  state.manager_->AddProvider(
      new MimeTypeTestProvider(&provider_state2, kExpectedMimeType), 0,
      std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

namespace {

// Content provider that adds another provider before or after the current
// provider.
class AddingTestProvider : public TestProvider {
 public:
  AddingTestProvider(State* state,
                     State* new_state,
                     CefResourceManager* manager,
                     bool before)
      : TestProvider(state),
        new_state_(new_state),
        manager_(manager),
        before_(before) {}

  bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
    TestProvider::OnRequest(request);

    manager_->AddProvider(
        new SimpleTestProvider(new_state_, SimpleTestProvider::CONTINUE,
                               nullptr),
        before_ ? -1 : 1, std::string());

    request->Continue(nullptr);
    return true;
  }

 private:
  State* new_state_;
  CefResourceManager* manager_;  // Weak reference.
  bool before_;

  DISALLOW_COPY_AND_ASSIGN(AddingTestProvider);
};

}  // namespace

// Test adding a new provider after the current provider.
TEST(ResourceManagerTest, AddProviderAfter) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new AddingTestProvider(&provider_state1, &provider_state2,
                             state.manager_.get(), false),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // All providers are called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  EXPECT_TRUE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}

// Test adding a new provider before the current provider.
TEST(ResourceManagerTest, AddProviderBefore) {
  const char kUrl[] = "http://test.com/ResourceManagerTest";

  ResourceManagerTestHandler::State state;
  state.urls_.push_back(kUrl);

  TestProvider::State provider_state1;
  TestProvider::State provider_state2;

  ProviderDestructHelper destruct_helper(2);
  provider_state1.destruct_callback_ = destruct_helper.callback();
  provider_state2.destruct_callback_ = destruct_helper.callback();

  state.manager_->AddProvider(
      new AddingTestProvider(&provider_state1, &provider_state2,
                             state.manager_.get(), true),
      0, std::string());

  CefRefPtr<ResourceManagerTestHandler> handler =
      new ResourceManagerTestHandler(&state);
  handler->ExecuteTest();

  ReleaseAndWaitForDestructor(handler);

  state.manager_ = nullptr;

  // Wait for the manager to be deleted.
  destruct_helper.Wait();

  // 1st provider is called.
  EXPECT_TRUE(provider_state1.got_on_request_);
  EXPECT_FALSE(provider_state1.got_on_request_canceled_);
  EXPECT_TRUE(provider_state1.got_destruct_);

  // 2nd provider is not called because it was added before the 1st provider.
  EXPECT_FALSE(provider_state2.got_on_request_);
  EXPECT_FALSE(provider_state2.got_on_request_canceled_);
  EXPECT_TRUE(provider_state2.got_destruct_);

  EXPECT_EQ(state.messages_.size(), 1U);
  EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
}
