// Copyright (c) 2012 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 "include/base/cef_bind.h"
#include "include/cef_process_message.h"
#include "include/cef_task.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/ceftests/test_handler.h"
#include "tests/ceftests/test_util.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/shared/renderer/client_app_renderer.h"

using client::ClientAppRenderer;

namespace {

// Unique values for the SendRecv test.
const char kSendRecvUrl[] = "http://tests/ProcessMessageTest.SendRecv";
const char kSendRecvMsg[] = "ProcessMessageTest.SendRecv";

// Creates a test message.
CefRefPtr<CefProcessMessage> CreateTestMessage() {
  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create(kSendRecvMsg);
  EXPECT_TRUE(msg.get());

  CefRefPtr<CefListValue> args = msg->GetArgumentList();
  EXPECT_TRUE(args.get());

  size_t index = 0;
  args->SetNull(index++);
  args->SetInt(index++, 5);
  args->SetDouble(index++, 10.543);
  args->SetBool(index++, true);
  args->SetString(index++, "test string");
  args->SetList(index++, args->Copy());

  EXPECT_EQ(index, args->GetSize());

  return msg;
}

// Renderer side.
class SendRecvRendererTest : public ClientAppRenderer::Delegate {
 public:
  SendRecvRendererTest() {}

  bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
                                CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefProcessId source_process,
                                CefRefPtr<CefProcessMessage> message) override {
    if (message->GetName() == kSendRecvMsg) {
      EXPECT_TRUE(browser.get());
      EXPECT_TRUE(frame.get());
      EXPECT_EQ(PID_BROWSER, source_process);
      EXPECT_TRUE(message.get());

      const std::string& url = frame->GetURL();
      if (url == kSendRecvUrl) {
        // Echo the message back to the sender natively.
        frame->SendProcessMessage(PID_BROWSER, message);
        return true;
      }
    }

    // Message not handled.
    return false;
  }

  IMPLEMENT_REFCOUNTING(SendRecvRendererTest);
};

// Browser side.
class SendRecvTestHandler : public TestHandler {
 public:
  explicit SendRecvTestHandler(cef_thread_id_t send_thread)
      : send_thread_(send_thread) {}

  void RunTest() override {
    message_ = CreateTestMessage();

    AddResource(kSendRecvUrl, "<html><body>TEST</body></html>", "text/html");
    CreateBrowser(kSendRecvUrl);

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

  void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                 CefRefPtr<CefFrame> frame,
                 int httpStatusCode) override {
    EXPECT_TRUE(CefCurrentlyOn(TID_UI));

    // Send the message to the renderer process.
    if (!CefCurrentlyOn(send_thread_)) {
      CefPostTask(send_thread_, base::Bind(&SendRecvTestHandler::SendMessage,
                                           this, browser, frame));
    } else {
      SendMessage(browser, frame);
    }
  }

  bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefProcessId source_process,
                                CefRefPtr<CefProcessMessage> message) override {
    EXPECT_TRUE(CefCurrentlyOn(TID_UI));
    EXPECT_TRUE(browser.get());
    EXPECT_TRUE(frame.get());
    EXPECT_EQ(PID_RENDERER, source_process);
    EXPECT_TRUE(message.get());
    EXPECT_TRUE(message->IsReadOnly());

    // Verify that the recieved message is the same as the sent message.
    TestProcessMessageEqual(message_, message);

    got_message_.yes();

    // Test is complete.
    DestroyTest();

    return true;
  }

 protected:
  void DestroyTest() override {
    EXPECT_TRUE(got_message_);
    TestHandler::DestroyTest();
  }

 private:
  void SendMessage(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
    EXPECT_TRUE(CefCurrentlyOn(send_thread_));
    frame->SendProcessMessage(PID_RENDERER, message_);
  }

  cef_thread_id_t send_thread_;

  CefRefPtr<CefProcessMessage> message_;
  TrackCallback got_message_;

  IMPLEMENT_REFCOUNTING(SendRecvTestHandler);
};

}  // namespace

// Verify send from the UI thread and recieve.
TEST(ProcessMessageTest, SendRecvUI) {
  CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_UI);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify send from the IO thread and recieve.
TEST(ProcessMessageTest, SendRecvIO) {
  CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_IO);
  handler->ExecuteTest();
  ReleaseAndWaitForDestructor(handler);
}

// Verify create.
TEST(ProcessMessageTest, Create) {
  CefRefPtr<CefProcessMessage> message =
      CefProcessMessage::Create(kSendRecvMsg);
  EXPECT_TRUE(message.get());
  EXPECT_TRUE(message->IsValid());
  EXPECT_FALSE(message->IsReadOnly());
  EXPECT_STREQ(kSendRecvMsg, message->GetName().ToString().c_str());

  CefRefPtr<CefListValue> args = message->GetArgumentList();
  EXPECT_TRUE(args.get());
  EXPECT_TRUE(args->IsValid());
  EXPECT_TRUE(args->IsOwned());
  EXPECT_FALSE(args->IsReadOnly());
}

// Verify copy.
TEST(ProcessMessageTest, Copy) {
  CefRefPtr<CefProcessMessage> message = CreateTestMessage();
  CefRefPtr<CefProcessMessage> message2 = message->Copy();
  TestProcessMessageEqual(message, message2);
}

// Entry point for creating process message renderer test objects.
// Called from client_app_delegates.cc.
void CreateProcessMessageRendererTests(
    ClientAppRenderer::DelegateSet& delegates) {
  // For ProcessMessageTest.SendRecv
  delegates.insert(new SendRecvRendererTest);
}
