// Copyright (c) 2020 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 <algorithm>
#include <sstream>

#include "include/base/cef_bind.h"
#include "include/cef_callback.h"
#include "include/cef_devtools_message_observer.h"
#include "include/cef_parser.h"
#include "include/wrapper/cef_closure_task.h"

#include "tests/ceftests/test_handler.h"
#include "tests/gtest/include/gtest/gtest.h"

namespace {

const char kTestUrl1[] = "http://tests/DevToolsMessage1";
const char kTestUrl2[] = "http://tests/DevToolsMessage2";

class DevToolsMessageTestHandler : public TestHandler {
 public:
  DevToolsMessageTestHandler() {}

  void RunTest() override {
    // Add HTML resources.
    AddResource(kTestUrl1, "<html><body>Test1</body></html>", "text/html");
    AddResource(kTestUrl2, "<html><body>Test2</body></html>", "text/html");

    // Create the browser.
    CreateBrowser(kTestUrl1);

    // Time out the test after a reasonable period of time.
    SetTestTimeout();
  }

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

    // STEP 1: Add the DevTools observer. Wait for the 1st load.
    registration_ = browser->GetHost()->AddDevToolsMessageObserver(
        new TestMessageObserver(this));
    EXPECT_TRUE(registration_);
  }

  void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                            bool isLoading,
                            bool canGoBack,
                            bool canGoForward) override {
    if (!isLoading) {
      load_ct_++;
      if (load_ct_ == 1) {
        // STEP 2: 1st load has completed. Now enable page domain notifications
        // and wait for the method result.
        ExecuteMethod("Page.enable", "",
                      base::Bind(&DevToolsMessageTestHandler::Navigate, this));
      } else if (load_ct_ == 2) {
        MaybeDestroyTest();
      }
    }
  }

  void DestroyTest() override {
    // STEP 7: Remove the DevTools observer. This should result in the observer
    // object being destroyed.
    EXPECT_TRUE(registration_);
    registration_ = nullptr;
    EXPECT_TRUE(observer_destroyed_);

    // Each send message variant should be called at least a single time.
    EXPECT_GE(method_send_ct_, 1);
    EXPECT_GE(method_execute_ct_, 1);

    // All sent messages should receive a result callback.
    EXPECT_EQ(expected_method_ct_, method_send_ct_ + method_execute_ct_);
    EXPECT_EQ(expected_method_ct_, result_ct_);
    EXPECT_EQ(expected_method_ct_, last_result_id_);

    // Every received message should parse successfully to a result or event
    // callback.
    EXPECT_EQ(message_ct_, result_ct_ + event_ct_);

    // Should receive 1 or more events (probably just 1, but who knows?).
    EXPECT_GE(event_ct_, 1);

    // OnLoadingStateChange(isLoading=false) should be called twice.
    EXPECT_EQ(expected_load_ct_, load_ct_);

    // Should get callbacks for agent attached but not detached.
    EXPECT_EQ(1, attached_ct_);
    EXPECT_EQ(0, detached_ct_);

    TestHandler::DestroyTest();
  }

 private:
  struct MethodResult {
    int message_id;
    bool success;
    std::string result;
  };

  struct Event {
    std::string method;
    std::string params;
  };

  class TestMessageObserver : public CefDevToolsMessageObserver {
   public:
    explicit TestMessageObserver(DevToolsMessageTestHandler* handler)
        : handler_(handler) {}

    virtual ~TestMessageObserver() { handler_->observer_destroyed_.yes(); }

    bool OnDevToolsMessage(CefRefPtr<CefBrowser> browser,
                           const void* message,
                           size_t message_size) override {
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(handler_->GetBrowserId(), browser->GetIdentifier());
      handler_->message_ct_++;
      return false;
    }

    void OnDevToolsMethodResult(CefRefPtr<CefBrowser> browser,
                                int message_id,
                                bool success,
                                const void* result,
                                size_t result_size) override {
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(handler_->GetBrowserId(), browser->GetIdentifier());
      handler_->result_ct_++;

      MethodResult mr;
      mr.message_id = message_id;
      mr.success = success;
      if (result) {
        // Intentionally truncating at small size.
        mr.result = std::string(static_cast<const char*>(result),
                                std::min(static_cast<int>(result_size), 80));
      }
      handler_->OnMethodResult(mr);
    }

    void OnDevToolsEvent(CefRefPtr<CefBrowser> browser,
                         const CefString& method,
                         const void* params,
                         size_t params_size) override {
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(handler_->GetBrowserId(), browser->GetIdentifier());
      handler_->event_ct_++;

      Event ev;
      ev.method = method;
      if (params) {
        // Intentionally truncating at small size.
        ev.params = std::string(static_cast<const char*>(params),
                                std::min(static_cast<int>(params_size), 80));
      }
      handler_->OnEvent(ev);
    }

    void OnDevToolsAgentAttached(CefRefPtr<CefBrowser> browser) override {
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(handler_->GetBrowserId(), browser->GetIdentifier());
      handler_->attached_ct_++;
    }

    void OnDevToolsAgentDetached(CefRefPtr<CefBrowser> browser) override {
      EXPECT_TRUE(browser.get());
      EXPECT_EQ(handler_->GetBrowserId(), browser->GetIdentifier());
      handler_->detached_ct_++;
    }

   private:
    DevToolsMessageTestHandler* handler_;

    IMPLEMENT_REFCOUNTING(TestMessageObserver);
    DISALLOW_COPY_AND_ASSIGN(TestMessageObserver);
  };

  // Execute a DevTools method. Expected results will be verified in
  // OnMethodResult, and |next_step| will then be executed.
  // |expected_result| can be a fragment that the result should start with.
  void ExecuteMethod(const std::string& method,
                     const std::string& params,
                     const base::Closure& next_step,
                     const std::string& expected_result = "{}",
                     bool expected_success = true) {
    CHECK(!method.empty());
    CHECK(!next_step.is_null());

    int message_id = next_message_id_++;

    std::stringstream message;
    message << "{\"id\":" << message_id << ",\"method\":\"" << method << "\"";
    if (!params.empty()) {
      message << ",\"params\":" << params;
    }
    message << "}";

    // Set expected result state.
    pending_message_ = message.str();
    pending_result_next_ = next_step;
    pending_result_ = {message_id, expected_success, expected_result};

    if (message_id % 2 == 0) {
      // Use the less structured method.
      method_send_ct_++;
      GetBrowser()->GetHost()->SendDevToolsMessage(pending_message_.data(),
                                                   pending_message_.size());
    } else {
      // Use the more structured method.
      method_execute_ct_++;
      CefRefPtr<CefDictionaryValue> dict;
      if (!params.empty()) {
        CefRefPtr<CefValue> value =
            CefParseJSON(params.data(), params.size(), JSON_PARSER_RFC);
        EXPECT_TRUE(value && value->GetType() == VTYPE_DICTIONARY)
            << "failed to parse: " << params;
        if (value && value->GetType() == VTYPE_DICTIONARY) {
          dict = value->GetDictionary();
        }
      }
      GetBrowser()->GetHost()->ExecuteDevToolsMethod(message_id, method, dict);
    }
  }

  // Every call to ExecuteMethod should result in a single call to this method
  // with the same message_id.
  void OnMethodResult(const MethodResult& result) {
    EXPECT_EQ(pending_result_.message_id, result.message_id)
        << "with message=" << pending_message_;
    if (result.message_id != pending_result_.message_id)
      return;

    EXPECT_EQ(pending_result_.success, result.success)
        << "with message=" << pending_message_;

    EXPECT_TRUE(result.result.find(pending_result_.result) == 0)
        << "with message=" << pending_message_
        << "\nand actual result=" << result.result
        << "\nand expected result=" << pending_result_.result;

    last_result_id_ = result.message_id;

    // Continue asynchronously to allow the callstack to unwind.
    CefPostTask(TID_UI, pending_result_next_);

    // Clear expected result state.
    pending_message_.clear();
    pending_result_next_.Reset();
    pending_result_ = {};
  }

  void OnEvent(const Event& event) {
    if (event.method != pending_event_.method)
      return;

    EXPECT_TRUE(event.params.find(pending_event_.params) == 0)
        << "with method=" << event.method
        << "\nand actual params=" << event.params
        << "\nand expected params=" << pending_event_.params;

    // Continue asynchronously to allow the callstack to unwind.
    CefPostTask(TID_UI, pending_event_next_);

    // Clear expected result state.
    pending_event_ = {};
    pending_event_next_.Reset();
  }

  void Navigate() {
    pending_event_ = {"Page.frameNavigated", "{\"frame\":"};
    pending_event_next_ =
        base::Bind(&DevToolsMessageTestHandler::AfterNavigate, this);

    std::stringstream params;
    params << "{\"url\":\"" << kTestUrl2 << "\"}";

    // STEP 3: Page domain notifications are enabled. Now start a new
    // navigation (but do nothing on method result) and wait for the
    // "Page.frameNavigated" event.
    ExecuteMethod("Page.navigate", params.str(), base::Bind(base::DoNothing),
                  /*expected_result=*/"{\"frameId\":");
  }

  void AfterNavigate() {
    // STEP 4: Got the "Page.frameNavigated" event. Now disable page domain
    // notifications.
    ExecuteMethod(
        "Page.disable", "",
        base::Bind(&DevToolsMessageTestHandler::AfterPageDisabled, this));
  }

  void AfterPageDisabled() {
    // STEP 5: Got the the "Page.disable" method result. Now call a non-existant
    // method to verify an error result, and then destroy the test when done.
    ExecuteMethod(
        "Foo.doesNotExist", "",
        base::Bind(&DevToolsMessageTestHandler::MaybeDestroyTest, this),
        /*expected_result=*/
        "{\"code\":-32601,\"message\":\"'Foo.doesNotExist' wasn't found\"}",
        /*expected_success=*/false);
  }

  void MaybeDestroyTest() {
    if (result_ct_ == expected_method_ct_ && load_ct_ == expected_load_ct_) {
      // STEP 6: Got confirmation of all expected method results and load
      // events. Now destroy the test.
      DestroyTest();
    }
  }

  // Total # of times we're planning to call ExecuteMethod.
  const int expected_method_ct_ = 4;

  // Total # of times we're expecting OnLoadingStateChange(isLoading=false) to
  // be called.
  const int expected_load_ct_ = 2;

  // In ExecuteMethod:
  //   Next message ID to use.
  int next_message_id_ = 1;
  //   Last message that was sent (used for debug messages only).
  std::string pending_message_;
  //   SendDevToolsMessage call count.
  int method_send_ct_ = 0;
  //   ExecuteDevToolsMethod call count.
  int method_execute_ct_ = 0;

  // Expect |pending_result_.message_id| in OnMethodResult.
  // The result should start with the |pending_result_.result| fragment.
  MethodResult pending_result_;
  //   Tracks the last message ID received.
  int last_result_id_ = -1;
  //   When received, execute this callback.
  base::Closure pending_result_next_;

  // Wait for |pending_event_.method| in OnEvent.
  // The params should start with the |pending_event_.params| fragment.
  Event pending_event_;
  //   When received, execute this callback.
  base::Closure pending_event_next_;

  CefRefPtr<CefRegistration> registration_;

  // Observer callback count.
  int message_ct_ = 0;
  int result_ct_ = 0;
  int event_ct_ = 0;
  int attached_ct_ = 0;
  int detached_ct_ = 0;

  // OnLoadingStateChange(isLoading=false) count.
  int load_ct_ = 0;

  TrackCallback observer_destroyed_;

  IMPLEMENT_REFCOUNTING(DevToolsMessageTestHandler);
  DISALLOW_COPY_AND_ASSIGN(DevToolsMessageTestHandler);
};

}  // namespace

// Test everything related to DevTools messages:
// - CefDevToolsMessageObserver registration and life span.
// - SendDevToolsMessage/ExecuteDevToolsMethod calls.
// - CefDevToolsMessageObserver callbacks for method results and events.
TEST(DevToolsMessageTest, Messages) {
  CefRefPtr<DevToolsMessageTestHandler> handler =
      new DevToolsMessageTestHandler();
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}
