// Copyright 2017 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/dom/custom_event.h"

#include <memory>
#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/optional.h"
#include "base/threading/platform_thread.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/cssom/viewport_size.h"
#include "cobalt/dom/custom_event_init.h"
#include "cobalt/dom/local_storage_database.h"
#include "cobalt/dom/testing/gtest_workarounds.h"
#include "cobalt/dom/testing/stub_environment_settings.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom_parser/parser.h"
#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/loader_factory.h"
#include "cobalt/media_session/media_session.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/script/source_code.h"
#include "cobalt/script/testing/fake_script_value.h"
#include "cobalt/script/value_handle.h"
#include "cobalt/script/wrappable.h"
#include "nb/pointer_arithmetic.h"
#include "starboard/window.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using cobalt::cssom::ViewportSize;
using cobalt::script::testing::FakeScriptValue;

namespace cobalt {
namespace dom {

class MockErrorCallback
    : public base::Callback<void(const base::Optional<std::string>&)> {
 public:
  MOCK_METHOD1(Run, void(const base::Optional<std::string>&));
};

namespace {
class CustomEventTest : public ::testing::Test {
 public:
  CustomEventTest()
      : message_loop_(base::MessageLoop::TYPE_DEFAULT),
        environment_settings_(new testing::StubEnvironmentSettings),
        css_parser_(css_parser::Parser::Create()),
        dom_parser_(new dom_parser::Parser(mock_error_callback_)),
        fetcher_factory_(new loader::FetcherFactory(NULL)),
        loader_factory_(new loader::LoaderFactory(
            "Test", fetcher_factory_.get(), NULL, null_debugger_hooks_, 0,
            base::ThreadPriority::DEFAULT)),
        local_storage_database_(NULL),
        url_("about:blank") {
    engine_ = script::JavaScriptEngine::CreateEngine();
    global_environment_ = engine_->CreateGlobalEnvironment();
    window_ = new Window(
        environment_settings_.get(), ViewportSize(1920, 1080),
        base::kApplicationStateStarted, css_parser_.get(), dom_parser_.get(),
        fetcher_factory_.get(), loader_factory_.get(), NULL, NULL, NULL, NULL,
        NULL, NULL, &local_storage_database_, NULL, NULL, NULL, NULL,
        global_environment_->script_value_factory(), NULL, NULL, url_, "",
        "en-US", "en", base::Callback<void(const GURL&)>(),
        base::Bind(&MockErrorCallback::Run,
                   base::Unretained(&mock_error_callback_)),
        NULL, network_bridge::PostSender(), csp::kCSPRequired,
        kCspEnforcementEnable, base::Closure() /* csp_policy_changed */,
        base::Closure() /* ran_animation_frame_callbacks */,
        dom::Window::CloseCallback() /* window_close */,
        base::Closure() /* window_minimize */, NULL, NULL, NULL,
        dom::Window::OnStartDispatchEventCallback(),
        dom::Window::OnStopDispatchEventCallback(),
        dom::ScreenshotManager::ProvideScreenshotFunctionCallback(), NULL);
    global_environment_->CreateGlobalObject(window_,
                                            environment_settings_.get());
  }

  bool EvaluateScript(const std::string& js_code, std::string* result);

 private:
  base::MessageLoop message_loop_;
  base::NullDebuggerHooks null_debugger_hooks_;
  std::unique_ptr<script::JavaScriptEngine> engine_;
  const std::unique_ptr<testing::StubEnvironmentSettings> environment_settings_;
  scoped_refptr<script::GlobalEnvironment> global_environment_;
  MockErrorCallback mock_error_callback_;
  std::unique_ptr<css_parser::Parser> css_parser_;
  std::unique_ptr<dom_parser::Parser> dom_parser_;
  std::unique_ptr<loader::FetcherFactory> fetcher_factory_;
  std::unique_ptr<loader::LoaderFactory> loader_factory_;
  dom::LocalStorageDatabase local_storage_database_;
  GURL url_;
  scoped_refptr<Window> window_;
};

bool CustomEventTest::EvaluateScript(const std::string& js_code,
                                     std::string* result) {
  DCHECK(global_environment_);
  DCHECK(result);
  scoped_refptr<script::SourceCode> source_code =
      script::SourceCode::CreateSourceCode(
          js_code, base::SourceLocation(__FILE__, __LINE__, 1));

  global_environment_->EnableEval();
  global_environment_->SetReportEvalCallback(base::Closure());
  bool succeeded = global_environment_->EvaluateScript(source_code, result);
  return succeeded;
}
}  // namespace

TEST_F(CustomEventTest, ConstructorWithEventTypeString) {
  scoped_refptr<CustomEvent> event = new CustomEvent("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());
  EXPECT_EQ(NULL, event->detail());
}

TEST_F(CustomEventTest, ConstructorWithEventTypeAndDefaultInitDict) {
  CustomEventInit init;
  scoped_refptr<CustomEvent> event = new CustomEvent("mytestevent", init);

  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());
  EXPECT_EQ(NULL, event->detail());
}

TEST_F(CustomEventTest, ConstructorWithEventTypeAndCustomInitDict) {
  std::string result;
  bool success = EvaluateScript(
      "var event = new CustomEvent('dog', "
      "    {'bubbles':true, "
      "     'cancelable':true, "
      "     'detail':{'cobalt':'rulez'}});"
      "if (event.type == 'dog' &&"
      "    event.bubbles == true &&"
      "    event.cancelable == true) "
      "    event.detail.cobalt;",
      &result);
  EXPECT_EQ("rulez", result);

  if (!success) {
    DLOG(ERROR) << "Failed to evaluate test: "
                << "\"" << result << "\"";
  } else {
    LOG(INFO) << "Test result : "
              << "\"" << result << "\"";
  }
}

TEST_F(CustomEventTest, InitCustomEvent) {
  std::string result;
  bool success = EvaluateScript(
      "var event = new CustomEvent('cat');\n"
      "event.initCustomEvent('dog', true, true, {cobalt:'rulez'});"
      "if (event.type == 'dog' &&"
      "    event.detail &&"
      "    event.bubbles == true &&"
      "    event.cancelable == true) "
      "    event.detail.cobalt;",
      &result);
  EXPECT_EQ("rulez", result);

  if (!success) {
    DLOG(ERROR) << "Failed to evaluate test: "
                << "\"" << result << "\"";
  } else {
    LOG(INFO) << "Test result : "
              << "\"" << result << "\"";
  }
}

}  // namespace dom
}  // namespace cobalt
