// 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/worker/extendable_message_event.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "cobalt/script/testing/fake_script_value.h"
#include "cobalt/script/v8c/entry_scope.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/web/testing/gtest_workarounds.h"
#include "cobalt/web/testing/mock_event_listener.h"
#include "cobalt/worker/extendable_message_event_init.h"
#include "cobalt/worker/testing/test_with_javascript.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace worker {

using script::testing::FakeScriptValue;
using web::testing::MockEventListener;

namespace {
class ExtendableMessageEventTestWithJavaScript
    : public testing::TestServiceWorkerWithJavaScript {
 protected:
  ExtendableMessageEventTestWithJavaScript() {
    fake_event_listener_ = MockEventListener::Create();
  }

  ~ExtendableMessageEventTestWithJavaScript() override {}

  std::unique_ptr<MockEventListener> fake_event_listener_;
};
}  // namespace

TEST_F(ExtendableMessageEventTestWithJavaScript,
       ConstructorWithEventTypeString) {
  scoped_refptr<ExtendableMessageEvent> event =
      new ExtendableMessageEvent("mytestevent");

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(web::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::Handle<script::ValueHandle> event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.IsEmpty());
}

TEST_F(ExtendableMessageEventTestWithJavaScript, ConstructorWithAny) {
  base::Optional<script::ValueHandleHolder::Reference> reference;
  EvaluateScript("'ConstructorWithAnyMessageData'", &reference);
  std::unique_ptr<script::DataBuffer> data(
      script::SerializeScriptValue(reference->referenced_value()));
  EXPECT_NE(nullptr, data.get());
  EXPECT_NE(nullptr, data->ptr);
  EXPECT_GT(data->size, 0U);
  scoped_refptr<ExtendableMessageEvent> event =
      new ExtendableMessageEvent(base::Tokens::message(), std::move(data));

  EXPECT_EQ("message", event->type());
  EXPECT_EQ(NULL, event->target().get());
  EXPECT_EQ(NULL, event->current_target().get());
  EXPECT_EQ(web::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::Handle<script::ValueHandle> event_data =
      event->data(web_context()->environment_settings());
  EXPECT_FALSE(event_data.IsEmpty());
  auto script_value = event_data.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("ConstructorWithAnyMessageData", actual);
}

TEST_F(ExtendableMessageEventTestWithJavaScript,
       ConstructorWithEventTypeAndDefaultInitDict) {
  ExtendableMessageEventInit init;
  scoped_refptr<ExtendableMessageEvent> event =
      new ExtendableMessageEvent("mytestevent", init);

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(nullptr, event->target().get());
  EXPECT_EQ(nullptr, event->current_target().get());
  EXPECT_EQ(web::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::Handle<script::ValueHandle> event_data =
      event->data(web_context()->environment_settings());
  EXPECT_TRUE(event_data.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_F(ExtendableMessageEventTestWithJavaScript,
       ConstructorWithEventTypeAndInitDict) {
  ExtendableMessageEventInit 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<ExtendableMessageEvent> event =
      new ExtendableMessageEvent("mytestevent", init);

  EXPECT_EQ("mytestevent", event->type());
  EXPECT_EQ(nullptr, event->target().get());
  EXPECT_EQ(nullptr, event->current_target().get());
  EXPECT_EQ(web::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::Handle<script::ValueHandle> event_data =
      event->data(web_context()->environment_settings());
  auto script_value = event_data.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_F(ExtendableMessageEventTestWithJavaScript,
       ConstructorWithEventTypeAndExtendableMessageEventInitDict) {
  std::string result;
  EXPECT_TRUE(
      EvaluateScript("var event = new ExtendableMessageEvent('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);
}

}  // namespace worker
}  // namespace cobalt
