// Copyright (c) 2013 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 "tests/ceftests/test_handler.h"

#include "include/base/cef_bind.h"
#include "include/base/cef_logging.h"
#include "include/cef_command_line.h"
#include "include/cef_stream.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/shared/common/client_switches.h"

#if defined(USE_AURA)
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#endif

namespace {

#if defined(USE_AURA)

// Delegate implementation for the CefWindow that will host the Views-based
// browser.
class TestWindowDelegate : public CefWindowDelegate {
 public:
  // Create a new top-level Window hosting |browser_view|.
  static void CreateBrowserWindow(CefRefPtr<CefBrowserView> browser_view,
                                  const std::string& title) {
    CefWindow::CreateTopLevelWindow(
        new TestWindowDelegate(browser_view, "CefUnitTestViews " + title));
  }

  // CefWindowDelegate methods:

  void OnWindowCreated(CefRefPtr<CefWindow> window) override {
    // Add the browser view and show the window.
    window->CenterWindow(CefSize(800, 600));
    window->SetTitle(title_);
    window->AddChildView(browser_view_);
    window->Show();
  }

  void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
    browser_view_ = nullptr;
  }

  bool CanClose(CefRefPtr<CefWindow> window) override {
    // Allow the window to close if the browser says it's OK.
    CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
    if (browser)
      return browser->GetHost()->TryCloseBrowser();
    return true;
  }

 private:
  TestWindowDelegate(CefRefPtr<CefBrowserView> browser_view,
                     const CefString& title)
      : browser_view_(browser_view), title_(title) {}

  CefRefPtr<CefBrowserView> browser_view_;
  CefString title_;

  IMPLEMENT_REFCOUNTING(TestWindowDelegate);
  DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
};

// Delegate implementation for the CefBrowserView.
class TestBrowserViewDelegate : public CefBrowserViewDelegate {
 public:
  TestBrowserViewDelegate() {}

  // CefBrowserViewDelegate methods:

  bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
                                 CefRefPtr<CefBrowserView> popup_browser_view,
                                 bool is_devtools) override {
    // Create our own Window for popups. It will show itself after creation.
    TestWindowDelegate::CreateBrowserWindow(popup_browser_view,
                                            is_devtools ? "DevTools" : "Popup");
    return true;
  }

 private:
  IMPLEMENT_REFCOUNTING(TestBrowserViewDelegate);
  DISALLOW_COPY_AND_ASSIGN(TestBrowserViewDelegate);
};

#endif  // defined(USE_AURA)

}  // namespace

// TestHandler::CompletionState

TestHandler::CompletionState::CompletionState(int total)
    : total_(total), count_(0) {
  event_ = CefWaitableEvent::CreateWaitableEvent(true, false);
}

void TestHandler::CompletionState::TestComplete() {
  if (++count_ == total_) {
    count_ = 0;

    // Signal that the test is now complete. Do not access any object members
    // after this call because |this| might be deleted.
    event_->Signal();
  }
}

void TestHandler::CompletionState::WaitForTests() {
  // Wait for the test to complete
  event_->Wait();

  // Reset the event so the same test can be executed again.
  event_->Reset();
}

// TestHandler::Collection

TestHandler::Collection::Collection(CompletionState* completion_state)
    : completion_state_(completion_state) {
  EXPECT_TRUE(completion_state_);
}

void TestHandler::Collection::AddTestHandler(TestHandler* test_handler) {
  EXPECT_EQ(test_handler->completion_state_, completion_state_);
  handler_list_.push_back(test_handler);
}

void TestHandler::Collection::ExecuteTests() {
  EXPECT_GT(handler_list_.size(), 0UL);

  TestHandlerList::const_iterator it;

  it = handler_list_.begin();
  for (; it != handler_list_.end(); ++it)
    (*it)->SetupTest();

  completion_state_->WaitForTests();

  it = handler_list_.begin();
  for (; it != handler_list_.end(); ++it)
    (*it)->RunTest();

  completion_state_->WaitForTests();
}

// TestHandler::UIThreadHelper

TestHandler::UIThreadHelper::UIThreadHelper() : weak_ptr_factory_(this) {}

void TestHandler::UIThreadHelper::PostTask(const base::Closure& task) {
  EXPECT_UI_THREAD();
  CefPostTask(TID_UI, base::Bind(&UIThreadHelper::TaskHelper,
                                 weak_ptr_factory_.GetWeakPtr(), task));
}

void TestHandler::UIThreadHelper::PostDelayedTask(const base::Closure& task,
                                                  int delay_ms) {
  EXPECT_UI_THREAD();
  CefPostDelayedTask(TID_UI,
                     base::Bind(&UIThreadHelper::TaskHelper,
                                weak_ptr_factory_.GetWeakPtr(), task),
                     delay_ms);
}

void TestHandler::UIThreadHelper::TaskHelper(const base::Closure& task) {
  EXPECT_UI_THREAD();
  task.Run();
}

// TestHandler

int TestHandler::browser_count_ = 0;

TestHandler::TestHandler(CompletionState* completion_state)
    : first_browser_id_(0),
      signal_completion_when_all_browsers_close_(true),
      destroy_event_(nullptr),
      destroy_test_expected_(true),
      destroy_test_called_(false) {
  if (completion_state) {
    completion_state_ = completion_state;
    completion_state_owned_ = false;
  } else {
    completion_state_ = new CompletionState(1);
    completion_state_owned_ = true;
  }
}

TestHandler::~TestHandler() {
  DCHECK(!ui_thread_helper_.get());
  if (destroy_test_expected_)
    EXPECT_TRUE(destroy_test_called_);
  else
    EXPECT_FALSE(destroy_test_called_);
  EXPECT_TRUE(browser_map_.empty());

  if (completion_state_owned_)
    delete completion_state_;

  if (destroy_event_)
    destroy_event_->Signal();
}

void TestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  EXPECT_UI_THREAD();

  browser_count_++;

  const int browser_id = browser->GetIdentifier();
  EXPECT_EQ(browser_map_.find(browser_id), browser_map_.end());
  if (browser_map_.empty()) {
    first_browser_id_ = browser_id;
    first_browser_ = browser;
  }
  browser_map_.insert(std::make_pair(browser_id, browser));
}

void TestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  EXPECT_UI_THREAD();

  // Free the browser pointer so that the browser can be destroyed.
  const int browser_id = browser->GetIdentifier();
  BrowserMap::iterator it = browser_map_.find(browser_id);
  EXPECT_NE(it, browser_map_.end());
  browser_map_.erase(it);

  if (browser_id == first_browser_id_) {
    first_browser_id_ = 0;
    first_browser_ = nullptr;
  }

  if (browser_map_.empty() && signal_completion_when_all_browsers_close_) {
    // Signal that the test is now complete.
    TestComplete();
  }

  browser_count_--;
}

namespace {

CefResponse::HeaderMap ToCefHeaderMap(
    const ResourceContent::HeaderMap& headerMap) {
  CefResponse::HeaderMap result;
  ResourceContent::HeaderMap::const_iterator it = headerMap.begin();
  for (; it != headerMap.end(); ++it) {
    result.insert(std::pair<CefString, CefString>(it->first, it->second));
  }
  return result;
}

}  // namespace

CefRefPtr<CefResourceHandler> TestHandler::GetResourceHandler(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefRequest> request) {
  EXPECT_IO_THREAD();

  if (resource_map_.size() > 0) {
    CefString url = request->GetURL();

    // Ignore the query component, if any.
    std::string urlStr = url;
    size_t idx = urlStr.find('?');
    if (idx > 0)
      urlStr = urlStr.substr(0, idx);

    ResourceMap::const_iterator it = resource_map_.find(urlStr);
    if (it != resource_map_.end()) {
      // Return the previously mapped resource
      CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
          static_cast<void*>(const_cast<char*>(it->second.content().c_str())),
          it->second.content().length());
      return new CefStreamResourceHandler(
          200, "OK", it->second.mimeType(),
          ToCefHeaderMap(it->second.headerMap()), stream);
    }
  }

  return nullptr;
}

void TestHandler::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
                                            TerminationStatus status) {
  LOG(WARNING) << "OnRenderProcessTerminated: status = " << status << ".";
}

CefRefPtr<CefBrowser> TestHandler::GetBrowser() {
  return first_browser_;
}

int TestHandler::GetBrowserId() {
  return first_browser_id_;
}

void TestHandler::GetAllBrowsers(BrowserMap* map) {
  EXPECT_UI_THREAD();
  EXPECT_TRUE(map);
  *map = browser_map_;
}

void TestHandler::ExecuteTest() {
  EXPECT_EQ(completion_state_->total(), 1);

  // Reset any state from the previous run.
  if (destroy_test_called_)
    destroy_test_called_ = false;

  // Run the test.
  RunTest();

  // Wait for the test to complete.
  completion_state_->WaitForTests();
}

void TestHandler::SetupComplete() {
  // Signal that the test setup is complete.
  completion_state_->TestComplete();
}

void TestHandler::DestroyTest() {
  if (!CefCurrentlyOn(TID_UI)) {
    CefPostTask(TID_UI, base::Bind(&TestHandler::DestroyTest, this));
    return;
  }

  EXPECT_TRUE(destroy_test_expected_);
  if (destroy_test_called_)
    return;
  destroy_test_called_ = true;

  if (!browser_map_.empty()) {
    // Use a copy of the map since the original may be modified while we're
    // iterating.
    BrowserMap browser_map = browser_map_;

    // Tell all browsers to close.
    BrowserMap::const_iterator it = browser_map.begin();
    for (; it != browser_map.end(); ++it)
      CloseBrowser(it->second, false);
  }

  if (ui_thread_helper_.get())
    ui_thread_helper_.reset(nullptr);
}

void TestHandler::OnTestTimeout(int timeout_ms, bool treat_as_error) {
  EXPECT_UI_THREAD();
  if (treat_as_error) {
    EXPECT_TRUE(false) << "Test timed out after " << timeout_ms << "ms";
  }
  DestroyTest();
}

void TestHandler::CreateBrowser(const CefString& url,
                                CefRefPtr<CefRequestContext> request_context,
                                CefRefPtr<CefDictionaryValue> extra_info) {
#if defined(USE_AURA)
  const bool use_views = CefCommandLine::GetGlobalCommandLine()->HasSwitch(
      client::switches::kUseViews);
  if (use_views && !CefCurrentlyOn(TID_UI)) {
    // Views classes must be accessed on the UI thread.
    CefPostTask(TID_UI, base::Bind(&TestHandler::CreateBrowser, this, url,
                                   request_context, extra_info));
    return;
  }
#endif  // defined(USE_AURA)

  CefWindowInfo windowInfo;
  CefBrowserSettings settings;
  PopulateBrowserSettings(&settings);

#if defined(USE_AURA)
  if (use_views) {
    // Create the BrowserView.
    CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
        this, url, settings, extra_info, request_context,
        new TestBrowserViewDelegate());

    // Create the Window. It will show itself after creation.
    TestWindowDelegate::CreateBrowserWindow(browser_view, std::string());
  } else
#endif  // defined(USE_AURA)
  {
#if defined(OS_WIN)
    windowInfo.SetAsPopup(nullptr, "CefUnitTest");
    windowInfo.style |= WS_VISIBLE;
#endif
    CefBrowserHost::CreateBrowser(windowInfo, this, url, settings, extra_info,
                                  request_context);
  }
}

// static
void TestHandler::CloseBrowser(CefRefPtr<CefBrowser> browser,
                               bool force_close) {
  browser->GetHost()->CloseBrowser(force_close);
}

void TestHandler::AddResource(const std::string& url,
                              const std::string& content,
                              const std::string& mime_type) {
  ResourceContent::HeaderMap headerMap = ResourceContent::HeaderMap();
  ResourceContent rc = ResourceContent(content, mime_type, headerMap);
  AddResourceEx(url, rc);
}

void TestHandler::AddResource(const std::string& url,
                              const std::string& content,
                              const std::string& mime_type,
                              const ResourceContent::HeaderMap& header_map) {
  ResourceContent rc = ResourceContent(content, mime_type, header_map);
  AddResourceEx(url, rc);
}

void TestHandler::AddResourceEx(const std::string& url,
                                const ResourceContent& content) {
  if (!CefCurrentlyOn(TID_IO)) {
    CefPostTask(TID_IO,
                base::Bind(&TestHandler::AddResourceEx, this, url, content));
    return;
  }

  // Ignore the query component, if any.
  std::string urlStr = url;
  size_t idx = urlStr.find('?');
  if (idx > 0)
    urlStr = urlStr.substr(0, idx);

  resource_map_.insert(std::make_pair(urlStr, content));
}

void TestHandler::ClearResources() {
  if (!CefCurrentlyOn(TID_IO)) {
    CefPostTask(TID_IO, base::Bind(&TestHandler::ClearResources, this));
    return;
  }

  resource_map_.clear();
}

void TestHandler::SetTestTimeout(int timeout_ms, bool treat_as_error) {
  if (!CefCurrentlyOn(TID_UI)) {
    CefPostTask(TID_UI, base::Bind(&TestHandler::SetTestTimeout, this,
                                   timeout_ms, treat_as_error));
    return;
  }

  if (destroy_test_called_) {
    // No need to set the timeout if the test has already completed.
    return;
  }

  if (treat_as_error && CefCommandLine::GetGlobalCommandLine()->HasSwitch(
                            "disable-test-timeout")) {
    return;
  }

  // Use a weak reference to |this| via UIThreadHelper so that the TestHandler
  // can be destroyed before the timeout expires.
  GetUIThreadHelper()->PostDelayedTask(
      base::Bind(&TestHandler::OnTestTimeout, base::Unretained(this),
                 timeout_ms, treat_as_error),
      timeout_ms);
}

void TestHandler::TestComplete() {
  if (!CefCurrentlyOn(TID_UI)) {
    CefPostTask(TID_UI, base::Bind(&TestHandler::TestComplete, this));
    return;
  }

  EXPECT_TRUE(browser_map_.empty());
  completion_state_->TestComplete();
}

TestHandler::UIThreadHelper* TestHandler::GetUIThreadHelper() {
  EXPECT_UI_THREAD();
  CHECK(!destroy_test_called_);

  if (!ui_thread_helper_.get())
    ui_thread_helper_.reset(new UIThreadHelper());
  return ui_thread_helper_.get();
}

// global functions

bool TestFailed() {
  CefRefPtr<CefCommandLine> command_line =
      CefCommandLine::GetGlobalCommandLine();
  if (command_line->HasSwitch("single-process")) {
    // Check for a failure on the current test only.
    return ::testing::UnitTest::GetInstance()
        ->current_test_info()
        ->result()
        ->Failed();
  } else {
    // Check for any global failure.
    return ::testing::UnitTest::GetInstance()->Failed();
  }
}
