// Copyright 2017 The Chromium 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 "extensions/renderer/bindings/event_emitter.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "extensions/renderer/bindings/api_binding_test.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "extensions/renderer/bindings/api_event_listeners.h"
#include "extensions/renderer/bindings/exception_handler.h"
#include "extensions/renderer/bindings/listener_tracker.h"
#include "extensions/renderer/bindings/test_js_runner.h"
#include "gin/handle.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace extensions {

namespace {

APIEventListeners::ContextOwnerIdGetter CreateContextOwnerIdGetter() {
  return base::BindRepeating(
      [](v8::Local<v8::Context>) { return std::string("context"); });
}

}  // namespace

class EventEmitterUnittest : public APIBindingTest {
 public:
  EventEmitterUnittest() = default;
  ~EventEmitterUnittest() override = default;

  // A helper method to dispose of a context and set a flag.
  void DisposeContextWrapper(bool* did_invalidate,
                             v8::Local<v8::Context> context) {
    EXPECT_FALSE(*did_invalidate);
    *did_invalidate = true;
    DisposeContext(context);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(EventEmitterUnittest);
};

TEST_F(EventEmitterUnittest, TestDispatchMethod) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  ListenerTracker tracker;
  auto listeners = std::make_unique<UnfilteredEventListeners>(
      base::DoNothing(), "event", CreateContextOwnerIdGetter(),
      binding::kNoListenerMax, true, &tracker);

  auto log_error = [](std::vector<std::string>* errors,
                      v8::Local<v8::Context> context,
                      const std::string& error) { errors->push_back(error); };

  std::vector<std::string> logged_errors;
  ExceptionHandler exception_handler(base::Bind(log_error, &logged_errors));

  gin::Handle<EventEmitter> event = gin::CreateHandle(
      isolate(),
      new EventEmitter(false, std::move(listeners), &exception_handler));

  v8::Local<v8::Value> v8_event = event.ToV8();

  const char kAddListener[] =
      "(function(event, listener) { event.addListener(listener); })";
  v8::Local<v8::Function> add_listener_function =
      FunctionFromString(context, kAddListener);

  auto add_listener = [context, v8_event,
                       add_listener_function](base::StringPiece listener) {
    v8::Local<v8::Function> listener_function =
        FunctionFromString(context, listener);
    v8::Local<v8::Value> args[] = {v8_event, listener_function};
    RunFunction(add_listener_function, context, base::size(args), args);
  };

  const char kListener1[] =
      "(function() {\n"
      "  this.eventArgs1 = Array.from(arguments);\n"
      "  return 'listener1';\n"
      "})";
  add_listener(kListener1);
  const char kListener2[] =
      "(function() {\n"
      "  this.eventArgs2 = Array.from(arguments);\n"
      "  return {listener: 'listener2'};\n"
      "})";
  add_listener(kListener2);
  // Listener3 throws, but shouldn't stop the event from reaching other
  // listeners.
  const char kListener3[] =
      "(function() {\n"
      "  this.eventArgs3 = Array.from(arguments);\n"
      "  throw new Error('hahaha');\n"
      "})";
  add_listener(kListener3);
  // Returning undefined should not be added to the array of results from
  // dispatch.
  const char kListener4[] =
      "(function() {\n"
      "  this.eventArgs4 = Array.from(arguments);\n"
      "})";
  add_listener(kListener4);

  const char kDispatch[] =
      "(function(event) {\n"
      "  return event.dispatch('arg1', 2);\n"
      "})";
  v8::Local<v8::Value> dispatch_args[] = {v8_event};
  TestJSRunner::AllowErrors allow_errors;
  v8::Local<v8::Value> dispatch_result =
      RunFunctionOnGlobal(FunctionFromString(context, kDispatch), context,
                          base::size(dispatch_args), dispatch_args);

  const char kExpectedEventArgs[] = "[\"arg1\",2]";
  for (const char* property :
       {"eventArgs1", "eventArgs2", "eventArgs3", "eventArgs4"}) {
    EXPECT_EQ(kExpectedEventArgs, GetStringPropertyFromObject(
                                      context->Global(), context, property));
  }
  EXPECT_EQ("{\"results\":[\"listener1\",{\"listener\":\"listener2\"}]}",
            V8ToString(dispatch_result, context));

  ASSERT_EQ(1u, logged_errors.size());
  EXPECT_THAT(logged_errors[0],
              testing::StartsWith("Error in event handler: Error: hahaha"));
}

// Test dispatching an event when the first listener invalidates the context.
// Nothing should break, and we shouldn't continue to dispatch the event.
TEST_F(EventEmitterUnittest, ListenersDestroyingContext) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context = MainContext();

  struct ListenerClosureData {
    EventEmitterUnittest& test;
    bool did_invalidate_context;
  } closure_data = {*this, false};

  // A wrapper that just calls DisposeContextWrapper() on the curried in data.
  auto listener_wrapper = [](const v8::FunctionCallbackInfo<v8::Value>& info) {
    ASSERT_TRUE(info.Data()->IsExternal());
    auto& data = *static_cast<ListenerClosureData*>(
        info.Data().As<v8::External>()->Value());
    data.test.DisposeContextWrapper(&data.did_invalidate_context,
                                    info.GetIsolate()->GetCurrentContext());
  };

  ListenerTracker tracker;
  auto listeners = std::make_unique<UnfilteredEventListeners>(
      base::DoNothing(), "event", CreateContextOwnerIdGetter(),
      binding::kNoListenerMax, true, &tracker);
  ExceptionHandler exception_handler(base::BindRepeating(
      [](v8::Local<v8::Context> context, const std::string& error) {}));
  gin::Handle<EventEmitter> event = gin::CreateHandle(
      isolate(),
      new EventEmitter(false, std::move(listeners), &exception_handler));

  v8::Local<v8::Value> v8_event = event.ToV8();

  const char kAddListener[] =
      "(function(event, listener) { event.addListener(listener); })";
  v8::Local<v8::Function> add_listener_function =
      FunctionFromString(context, kAddListener);

  // Queue up three listeners. The first triggered will invalidate the context.
  // The others should never be triggered.
  constexpr size_t kNumListeners = 3;
  for (size_t i = 0; i < kNumListeners; ++i) {
    v8::Local<v8::Function> listener =
        v8::Function::New(context, listener_wrapper,
                          v8::External::New(isolate(), &closure_data))
            .ToLocalChecked();
    v8::Local<v8::Value> args[] = {v8_event, listener};
    RunFunction(add_listener_function, context, base::size(args), args);
  }

  EXPECT_EQ(kNumListeners, event->GetNumListeners());

  std::vector<v8::Local<v8::Value>> args;
  event->Fire(context, &args, nullptr, JSRunner::ResultCallback());

  EXPECT_TRUE(closure_data.did_invalidate_context);
}

}  // namespace extensions
