// 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.

#ifndef CEF_TESTS_CEFTESTS_TEST_HANDLER_H_
#define CEF_TESTS_CEFTESTS_TEST_HANDLER_H_
#pragma once

#include <atomic>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <utility>

#include "include/base/cef_callback.h"
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "include/cef_frame.h"
#include "include/cef_task.h"
#include "include/cef_waitable_event.h"
#include "tests/ceftests/thread_helper.h"
#include "tests/ceftests/track_callback.h"
#include "tests/gtest/include/gtest/gtest.h"

class ResourceContent {
 public:
  typedef std::multimap<std::string, std::string> HeaderMap;

  ResourceContent(const std::string& content,
                  const std::string& mime_type,
                  const HeaderMap& header_map)
      : content_(content), mime_type_(mime_type), header_map_(header_map) {}

  const std::string& content() const { return content_; }
  const std::string& mimeType() const { return mime_type_; }
  const HeaderMap& headerMap() const { return header_map_; }

 private:
  std::string content_;
  std::string mime_type_;
  HeaderMap header_map_;
};

// Base implementation of CefClient for unit tests. Add new interfaces as needed
// by test cases.
class TestHandler : public CefClient,
                    public CefDialogHandler,
                    public CefDisplayHandler,
                    public CefDownloadHandler,
                    public CefJSDialogHandler,
                    public CefLifeSpanHandler,
                    public CefLoadHandler,
                    public CefRequestHandler,
                    public CefResourceRequestHandler {
 public:
  // Tracks the completion state of related test runs.
  class CompletionState {
   public:
    // |total| is the number of times that TestComplete() must be called before
    // WaitForTests() will return.
    explicit CompletionState(int total);

    // Call this method to indicate that a test has completed.
    void TestComplete();

    // This method blocks until TestComplete() has been called the required
    // number of times.
    void WaitForTests();

    int total() const { return total_; }
    int count() const { return count_; }

   private:
    int total_;
    int count_;

    // Handle used to notify when the test is complete
    CefRefPtr<CefWaitableEvent> event_;
  };

  // Represents a collection of related tests that need to be run
  // simultaniously.
  class Collection {
   public:
    // The |completion_state| object must outlive this class.
    explicit Collection(CompletionState* completion_state);

    // The |test_handler| object must outlive this class and it must share the
    // same CompletionState object passed to the constructor.
    void AddTestHandler(TestHandler* test_handler);

    // Manages the test run.
    // 1. Calls TestHandler::SetupTest() for all of the test objects.
    // 2. Waits for all TestHandler objects to report that initial setup is
    //    complete by calling TestHandler::SetupComplete().
    // 3. Calls TestHandler::RunTest() for all of the test objects.
    // 4. Waits for all TestHandler objects to report that the test is
    //    complete by calling TestHandler::DestroyTest().
    void ExecuteTests();

   private:
    CompletionState* completion_state_;

    typedef std::list<TestHandler*> TestHandlerList;
    TestHandlerList handler_list_;
  };

  typedef std::map<int, CefRefPtr<CefBrowser>> BrowserMap;

  // Helper for executing methods using WeakPtr references to TestHandler.
  class UIThreadHelper {
   public:
    UIThreadHelper();

    // Pass in a |task| with an unretained reference to TestHandler. |task| will
    // be executed only if TestHandler::DestroyTest has not yet been called.
    // For example:
    //    GetUIThreadHelper()->PostTask(
    //        base::BindOnce(&TestHandler::DoSomething,
    //        base::Unretained(this)));
    void PostTask(base::OnceClosure task);
    void PostDelayedTask(base::OnceClosure task, int delay_ms);

   private:
    void TaskHelper(base::OnceClosure task);

    // Must be the last member.
    base::WeakPtrFactory<UIThreadHelper> weak_ptr_factory_;
  };

  // The |completion_state| object if specified must outlive this class.
  explicit TestHandler(CompletionState* completion_state = nullptr);
  ~TestHandler() override;

  // Implement this method to set up the test. Only used in combination with a
  // Collection. Call SetupComplete() once the setup is complete.
  virtual void SetupTest() {}

  // Implement this method to run the test. Call DestroyTest() once the test is
  // complete.
  virtual void RunTest() = 0;

  // CefClient methods. Add new methods as needed by test cases.
  CefRefPtr<CefDialogHandler> GetDialogHandler() override { return this; }
  CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; }
  CefRefPtr<CefDownloadHandler> GetDownloadHandler() override { return this; }
  CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override { return this; }
  CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
  CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
  CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }

  // CefDownloadHandler methods
  void OnBeforeDownload(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefDownloadItem> download_item,
      const CefString& suggested_name,
      CefRefPtr<CefBeforeDownloadCallback> callback) override {}

  // CefLifeSpanHandler methods
  void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
  void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;

  // CefRequestHandler methods
  CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      bool is_navigation,
      bool is_download,
      const CefString& request_initiator,
      bool& disable_default_handling) override {
    return this;
  }

  // CefResourceRequestHandler methods
  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) override;

  void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
                                 TerminationStatus status) override;

  // These methods should only be used if at most one non-popup browser exists.
  CefRefPtr<CefBrowser> GetBrowser() const;
  int GetBrowserId() const;

  // Copies the map of all the currently existing browsers into |map|. Must be
  // called on the UI thread.
  void GetAllBrowsers(BrowserMap* map);

  // Called by the test function to execute the test. This method blocks until
  // the test is complete. Do not reference the object after this method
  // returns. Do not use this method if the CompletionState object is shared by
  // multiple handlers or when using a Collection object.
  void ExecuteTest();

  // Event that will be signaled from the TestHandler destructor.
  // Used by ReleaseAndWaitForDestructor.
  void SetDestroyEvent(CefRefPtr<CefWaitableEvent> event) {
    destroy_event_ = event;
  }

  // If a test will not call DestroyTest() indicate so using this method.
  void SetDestroyTestExpected(bool expected) {
    destroy_test_expected_ = expected;
  }

  // Called from TestWindowDelegate when Views is enabled.
  void OnWindowCreated(int browser_id);
  void OnWindowDestroyed(int browser_id);

  // Returns true if a TestHandler currently exists.
  static bool HasTestHandler() {
    return test_handler_count_.load(std::memory_order_relaxed) > 0U;
  }

  std::string debug_string_prefix() const { return debug_string_prefix_; }

 protected:
  // Indicate that test setup is complete. Only used in combination with a
  // Collection.
  virtual void SetupComplete();

  // Close any remaining browsers. This may result in a call to TestComplete(),
  // depending on the configuration of SetSignalCompletionCount().
  virtual void DestroyTest();

  // Called on the UI thread if the test times out as a result of calling
  // SetTestTimeout(). Calls DestroyTest() by default.
  virtual void OnTestTimeout(int timeout_ms, bool treat_as_error);

  void CreateBrowser(const CefString& url,
                     CefRefPtr<CefRequestContext> request_context = nullptr,
                     CefRefPtr<CefDictionaryValue> extra_info = nullptr);
  static void CloseBrowser(CefRefPtr<CefBrowser> browser, bool force_close);

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

  void AddResourceEx(const std::string& url, const ResourceContent& content);

  void ClearResources();

  // Specify the number of times that SignalTestCompletion() needs to be
  // explicitly called for test completion. Must be configured during test
  // initialization before any browsers are created.
  // - If the test creates browsers and does not explicitly call
  //   SignalTestCompletion() then the default value (0) can be used.
  // - If the test creates browsers and explicitly calls SignalTestCompletion()
  //   then set a value >= 1.
  // - If the test does not create browsers then it must explicitly call
  //   SignalTestCompletion() and set a value >= 1.
  void SetSignalTestCompletionCount(size_t count);

  // Explicitly signal test completion a single time. Used in combination with
  // SetSignalTestCompletionCount(). Results in a call to TestComplete() if
  // all browsers have closed and this method has been called the expected
  // number of times.
  void SignalTestCompletion();

  // Returns true if SignalTestCompletion() has been called the necessary
  // number of times (may be 0), in which case TestComplete() will be called
  // automatically when all browsers have closed. Must be called on the
  // UI thread.
  bool AllowTestCompletionWhenAllBrowsersClose() const;

  // Returns true if all browsers have closed. Must be called on the UI
  // thread.
  bool AllBrowsersClosed() const;

  // Call OnTestTimeout() after the specified amount of time.
  void SetTestTimeout(int timeout_ms = 5000, bool treat_as_error = true);

  // Call prior to CreateBrowser() to configure whether browsers will be created
  // as Views-hosted. Defaults to false unless the `--use-views` command-line
  // flag is specified.
  void SetUseViews(bool use_views);

  // Returns the single UIThreadHelper instance, creating it if necessary. Must
  // be called on the UI thread.
  UIThreadHelper* GetUIThreadHelper();

 private:
  void MaybeTestComplete();

  // Complete the test. It is an error to call this method before all browsers
  // have closed.
  void TestComplete();

  enum NotifyType {
    NT_BROWSER,
    NT_WINDOW,
  };
  void OnCreated(int browser_id, NotifyType type, bool views_hosted);
  void OnClosed(int browser_id, NotifyType type);

  std::string MakeDebugStringPrefix() const;
  const std::string debug_string_prefix_;

  // Used to notify when the test is complete. Can be accessed on any thread.
  CompletionState* completion_state_;
  bool completion_state_owned_;

  bool use_views_;

  // Map of browser ID to browser object. Only accessed on the UI thread.
  BrowserMap browser_map_;

  struct NotifyStatus {
    // True if this particular browser window is Views-hosted (see SetUseViews).
    // Some tests create popup or DevTools windows with default handling (e.g.
    // not Views-hosted).
    bool views_hosted;

    // Keyed by NotifyType.
    TrackCallback got_created[2];
    TrackCallback got_closed[2];
  };

  // Map of browser ID to current status. Only accessed on the UI thread.
  std::map<int, NotifyStatus> browser_status_map_;

  // Values for the first created browser. Modified on the UI thread but can be
  // accessed on any thread.
  int first_browser_id_ = 0;
  CefRefPtr<CefBrowser> first_browser_;

  // Map of resources that can be automatically loaded. Only accessed on the
  // IO thread.
  typedef std::map<std::string, ResourceContent> ResourceMap;
  ResourceMap resource_map_;

  // Number of times that SignalTestCompletion() must be called.
  size_t signal_completion_count_ = 0U;

  CefRefPtr<CefWaitableEvent> destroy_event_;

  // Tracks whether OnTestTimeout() has been called.
  bool test_timeout_called_ = false;

  // Tracks whether DestroyTest() is expected or has been called.
  bool destroy_test_expected_ = true;
  bool destroy_test_called_ = false;

  std::unique_ptr<UIThreadHelper> ui_thread_helper_;

  // Used to track the number of currently existing TestHandlers.
  static std::atomic<size_t> test_handler_count_;

  DISALLOW_COPY_AND_ASSIGN(TestHandler);
};

// Release |handler| and wait for the destructor to be called.
// This function is used to avoid test state leakage and to verify that
// all Handler references have been released on test completion.
template <typename T>
void ReleaseAndWaitForDestructor(CefRefPtr<T>& handler, int delay_ms = 2000) {
  CefRefPtr<CefWaitableEvent> event =
      CefWaitableEvent::CreateWaitableEvent(true, false);
  handler->SetDestroyEvent(event);
  T* _handler_ptr = handler.get();
  handler = nullptr;
  bool handler_destructed = event->TimedWait(delay_ms);
  EXPECT_TRUE(handler_destructed);
  if (!handler_destructed) {
    // |event| is a stack variable so clear the reference before returning.
    _handler_ptr->SetDestroyEvent(nullptr);
  }
}

// Returns true if the currently running test has failed.
bool TestFailed();

// Helper macros for executing checks in a method with a boolean return value.
// For example:
//
// bool VerifyVals(bool a, bool b) {
//   V_DECLARE();
//   V_EXPECT_TRUE(a);
//   V_EXPECT_FALSE(b);
//   V_RETURN();
// }
//
// EXPECT_TRUE(VerifyVals(true, false));

#define V_DECLARE()     \
  bool __verify = true; \
  bool __result

#define V_RETURN() return __verify

#define V_EXPECT_TRUE(condition)                         \
  __result = !!(condition);                              \
  __verify &= __result;                                  \
  GTEST_TEST_BOOLEAN_(__result, #condition, false, true, \
                      GTEST_NONFATAL_FAILURE_)

#define V_EXPECT_FALSE(condition)                           \
  __result = !!(condition);                                 \
  __verify &= !__result;                                    \
  GTEST_TEST_BOOLEAN_(!(__result), #condition, true, false, \
                      GTEST_NONFATAL_FAILURE_)

#endif  // CEF_TESTS_CEFTESTS_TEST_HANDLER_H_
