// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/web/message_event.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "cobalt/script/v8c/entry_scope.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/web/blob.h"
#include "cobalt/web/environment_settings_helper.h"
#include "cobalt/web/message_event_init.h"
#include "cobalt/web/testing/gtest_workarounds.h"
#include "cobalt/web/testing/test_with_javascript.h"
#include "net/base/io_buffer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace web {

namespace {
class MessageEventTestWithJavaScript : public testing::TestWebWithJavaScript {};
}  // namespace

TEST(MessageEventTest, ConstructorWithEventTypeString) {
  scoped_refptr<MessageEvent> event = new MessageEvent("mytestevent");

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());
  MessageEvent::Response event_data = event->data();
  EXPECT_TRUE(event_data.IsType<script::Handle<script::ValueHandle>>());
  EXPECT_TRUE(
      event_data.AsType<script::Handle<script::ValueHandle>>().IsEmpty());
}

TEST(MessageEventTest, ConstructorWithText) {
  std::string message_string("ConstructorWithTextMessageData");
  scoped_refptr<net::IOBufferWithSize> data =
      base::MakeRefCounted<net::IOBufferWithSize>(message_string.size());
  memcpy(data->data(), message_string.c_str(), message_string.size());
  scoped_refptr<MessageEvent> event =
      new MessageEvent(base::Tokens::message(), MessageEvent::kText, data);

  EXPECT_EQ("message", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());
  MessageEvent::Response event_data = event->data();
  EXPECT_TRUE(event_data.IsType<std::string>());
  EXPECT_EQ(message_string.size(), event_data.AsType<std::string>().size());
  EXPECT_EQ("ConstructorWithTextMessageData", event_data.AsType<std::string>());
}

TEST_P(MessageEventTestWithJavaScript, ConstructorWithBlob) {
  std::string message_string("ConstructorWithBlobMessageData");
  scoped_refptr<net::IOBufferWithSize> data =
      base::MakeRefCounted<net::IOBufferWithSize>(message_string.size());
  memcpy(data->data(), message_string.c_str(), message_string.size());
  scoped_refptr<MessageEvent> event =
      new MessageEvent(base::Tokens::message(), MessageEvent::kBlob, data);

  EXPECT_EQ("message", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());
  MessageEvent::Response event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsType<scoped_refptr<Blob>>());
  EXPECT_EQ(message_string.size(),
            event_data.AsType<scoped_refptr<Blob>>()->size());
  EXPECT_EQ("ConstructorWithBlobMessageData",
            std::string(reinterpret_cast<const char*>(
                            event_data.AsType<scoped_refptr<Blob>>()->data()),
                        static_cast<size_t>(
                            event_data.AsType<scoped_refptr<Blob>>()->size())));
  EXPECT_TRUE(event_data.AsType<scoped_refptr<Blob>>()->type().empty());
}

TEST_P(MessageEventTestWithJavaScript, ConstructorWithArrayBuffer) {
  std::string message_string("ConstructorWithArrayBufferMessageData");
  scoped_refptr<net::IOBufferWithSize> data =
      base::MakeRefCounted<net::IOBufferWithSize>(message_string.size());
  memcpy(data->data(), message_string.c_str(), message_string.size());
  scoped_refptr<MessageEvent> event = new MessageEvent(
      base::Tokens::message(), MessageEvent::kArrayBuffer, data);

  EXPECT_EQ("message", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());
  MessageEvent::Response event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsType<script::Handle<script::ArrayBuffer>>());
  EXPECT_EQ(
      message_string.size(),
      event_data.AsType<script::Handle<script::ArrayBuffer>>()->ByteLength());
  EXPECT_EQ(
      "ConstructorWithArrayBufferMessageData",
      std::string(
          reinterpret_cast<const char*>(
              event_data.AsType<script::Handle<script::ArrayBuffer>>()->Data()),
          static_cast<size_t>(
              event_data.AsType<script::Handle<script::ArrayBuffer>>()
                  ->ByteLength())));
}

TEST_P(MessageEventTestWithJavaScript, ConstructorWithAny) {
  base::Optional<script::ValueHandleHolder::Reference> reference;
  EvaluateScript("'ConstructorWithAnyMessageData'", &reference);
  auto* isolate = web::get_isolate(web_context()->environment_settings());
  auto structured_clone =
      std::make_unique<script::StructuredClone>(reference->referenced_value());
  scoped_refptr<MessageEvent> event =
      new MessageEvent(base::Tokens::message(), std::move(structured_clone));

  EXPECT_EQ("message", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());
  script::v8c::EntryScope entry_scope(isolate);
  MessageEvent::Response event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsType<script::Handle<script::ValueHandle>>());
  EXPECT_FALSE(
      event_data.AsType<script::Handle<script::ValueHandle>>().IsEmpty());
  auto script_value =
      event_data.AsType<script::Handle<script::ValueHandle>>().GetScriptValue();
  v8::Local<v8::Value> v8_value = script::GetV8Value(*script_value);
  std::string actual =
      *(v8::String::Utf8Value(isolate, v8_value.As<v8::String>()));
  EXPECT_EQ("ConstructorWithAnyMessageData", actual);
}

TEST_P(MessageEventTestWithJavaScript,
       ConstructorWithEventTypeAndDefaultInitDict) {
  MessageEventInit init;
  scoped_refptr<MessageEvent> event = new MessageEvent("mytestevent", init);

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(nullptr, event->target().get());
  EXPECT_EQ(nullptr, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());

  MessageEvent::Response event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsType<script::Handle<script::ValueHandle>>());
  EXPECT_TRUE(
      event_data.AsType<script::Handle<script::ValueHandle>>().IsEmpty());

  EXPECT_TRUE(event->origin().empty());
  EXPECT_TRUE(event->last_event_id().empty());
  EXPECT_EQ(nullptr, event->source().get());
  EXPECT_TRUE(event->ports().empty());
}

TEST_P(MessageEventTestWithJavaScript, ConstructorWithEventTypeAndInitDict) {
  MessageEventInit init;
  base::Optional<script::ValueHandleHolder::Reference> reference;
  EvaluateScript("'data_value'", &reference);
  init.set_data(&(reference->referenced_value()));
  init.set_origin("OriginString");
  init.set_last_event_id("lastEventIdString");
  init.set_source(web_context()->GetWindowOrWorkerGlobalScope());
  scoped_refptr<MessageEvent> event = new MessageEvent("mytestevent", init);

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(nullptr, event->target().get());
  EXPECT_EQ(nullptr, event->current_target().get());
  EXPECT_EQ(Event::kNone, event->event_phase());
  EXPECT_FALSE(event->bubbles());
  EXPECT_FALSE(event->cancelable());
  EXPECT_FALSE(event->default_prevented());
  EXPECT_FALSE(event->IsBeingDispatched());
  EXPECT_FALSE(event->propagation_stopped());
  EXPECT_FALSE(event->immediate_propagation_stopped());

  MessageEvent::Response event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsType<script::Handle<script::ValueHandle>>());
  auto script_value =
      event_data.AsType<script::Handle<script::ValueHandle>>().GetScriptValue();
  auto* isolate = script::GetIsolate(*script_value);
  script::v8c::EntryScope entry_scope(isolate);
  v8::Local<v8::Value> v8_value = script::GetV8Value(*script_value);
  std::string actual =
      *(v8::String::Utf8Value(isolate, v8_value.As<v8::String>()));
  EXPECT_EQ("data_value", actual);

  EXPECT_EQ("OriginString", event->origin());
  EXPECT_EQ("lastEventIdString", event->last_event_id());
  EXPECT_EQ(web_context()->GetWindowOrWorkerGlobalScope(),
            event->source().get());
  EXPECT_TRUE(event->ports().empty());
}

TEST_P(MessageEventTestWithJavaScript,
       ConstructorWithEventTypeAndMessageEventInitDict) {
  std::string result;
  EXPECT_TRUE(
      EvaluateScript("var event = new MessageEvent('dog', "
                     "    {cancelable: true, "
                     "     origin: 'OriginValue',"
                     "     lastEventId: 'LastEventIdValue',"
                     "     source: this,"
                     "     data: {value: 'data_value'},"
                     "    }"
                     ");"
                     "if (event.type == 'dog' &&"
                     "    event.bubbles == false &&"
                     "    event.cancelable == true &&"
                     "    event.origin == 'OriginValue' &&"
                     "    event.lastEventId == 'LastEventIdValue' &&"
                     "    event.source == this &&"
                     "    event.ports.length == 0 &&"
                     "    event.data.value == 'data_value') "
                     "    event.data.value;",
                     &result))
      << "Failed to evaluate script.";
  EXPECT_EQ("data_value", result);
}

INSTANTIATE_TEST_CASE_P(
    MessageEventTestsWithJavaScript, MessageEventTestWithJavaScript,
    ::testing::ValuesIn(testing::TestWebWithJavaScript::GetWebTypes()),
    testing::TestWebWithJavaScript::GetTypeName);

}  // namespace web
}  // namespace cobalt
