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

#include <string>

#include "base/bind.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "extensions/renderer/bindings/api_binding_test.h"
#include "extensions/renderer/bindings/api_binding_test_util.h"
#include "gin/converter.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace extensions {

namespace {

void PopulateError(base::Optional<std::string>* error_out,
                   v8::Local<v8::Context> context,
                   const std::string& error) {
  *error_out = error;
}

void ThrowException(v8::Local<v8::Context> context,
                    const std::string& to_throw,
                    ExceptionHandler* handler) {
  v8::Isolate* isolate = context->GetIsolate();
  v8::TryCatch try_catch(isolate);
  v8::Local<v8::Function> function = FunctionFromString(
      context,
      base::StringPrintf("(function() { throw %s; })", to_throw.c_str()));
  ignore_result(function->Call(context, v8::Undefined(isolate), 0, nullptr));
  ASSERT_TRUE(try_catch.HasCaught());
  handler->HandleException(context, "handled", &try_catch);
}

}  // namespace

using ExceptionHandlerTest = APIBindingTest;

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

  base::Optional<std::string> logged_error;
  ExceptionHandler handler(base::BindRepeating(&PopulateError, &logged_error));

  ThrowException(context, "new Error('some error')", &handler);

  ASSERT_TRUE(logged_error);
  EXPECT_THAT(*logged_error, testing::StartsWith("handled: Error: some error"));
}

TEST_F(ExceptionHandlerTest, PerContextHandlers) {
  v8::HandleScope handle_scope(isolate());
  v8::Local<v8::Context> context_a = MainContext();
  v8::Local<v8::Context> context_b = AddContext();

  base::Optional<std::string> logged_error;
  ExceptionHandler handler(base::BindRepeating(&PopulateError, &logged_error));

  v8::Local<v8::Function> custom_handler = FunctionFromString(
      context_a,
      "(function(message, exception) {\n"
      "  this.loggedMessage = message;\n"
      "  this.loggedExceptionMessage = exception && exception.message;\n"
      "})");

  handler.SetHandlerForContext(context_a, custom_handler);
  ThrowException(context_a, "new Error('context a error')", &handler);
  EXPECT_FALSE(logged_error);
  EXPECT_THAT(GetStringPropertyFromObject(context_a->Global(), context_a,
                                          "loggedMessage"),
              testing::StartsWith("\"handled: Error: context a error"));
  EXPECT_EQ("\"context a error\"",
            GetStringPropertyFromObject(context_a->Global(), context_a,
                                        "loggedExceptionMessage"));

  ASSERT_TRUE(context_a->Global()
                  ->Set(context_a,
                        gin::StringToSymbol(isolate(), "loggedMessage"),
                        v8::Undefined(isolate()))
                  .ToChecked());
  ASSERT_TRUE(
      context_a->Global()
          ->Set(context_a,
                gin::StringToSymbol(isolate(), "loggedExceptionMessage"),
                v8::Undefined(isolate()))
          .ToChecked());

  ThrowException(context_b, "new Error('context b error')", &handler);
  ASSERT_TRUE(logged_error);
  EXPECT_THAT(*logged_error,
              testing::StartsWith("handled: Error: context b error"));
  EXPECT_EQ("undefined", GetStringPropertyFromObject(
                             context_a->Global(), context_a, "loggedMessage"));
  EXPECT_EQ("undefined",
            GetStringPropertyFromObject(context_a->Global(), context_a,
                                        "loggedExceptionMessage"));
}

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

  base::Optional<std::string> logged_error;
  ExceptionHandler handler(base::BindRepeating(&PopulateError, &logged_error));

  ThrowException(context, "'hello'", &handler);
  ASSERT_TRUE(logged_error);
  EXPECT_EQ("handled: Uncaught hello", *logged_error);
  logged_error.reset();

  ThrowException(context, "{ message: 'hello' }", &handler);
  ASSERT_TRUE(logged_error);
  EXPECT_EQ("handled: Uncaught #<Object>", *logged_error);
  logged_error.reset();

  ThrowException(context, "{ toString: function() { throw 'goodbye' } }",
                 &handler);
  ASSERT_TRUE(logged_error);
  EXPECT_EQ("handled: Uncaught [object Object]", *logged_error);

  v8::Local<v8::Function> custom_handler =
      FunctionFromString(context,
                         "(function(message, exception) {\n"
                         "  this.loggedMessage = message;\n"
                         "  this.loggedException = exception;\n"
                         "})");

  handler.SetHandlerForContext(context, custom_handler);
  ThrowException(context, "'hello'", &handler);
  EXPECT_EQ(
      "\"handled: Uncaught hello\"",
      GetStringPropertyFromObject(context->Global(), context, "loggedMessage"));
  EXPECT_EQ("\"hello\"", GetStringPropertyFromObject(context->Global(), context,
                                                     "loggedException"));
}

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

  base::Optional<std::string> logged_error;
  ExceptionHandler handler(base::BindRepeating(&PopulateError, &logged_error));

  {
    v8::TryCatch try_catch(isolate());
    v8::Local<v8::Script> script =
        v8::Script::Compile(context,
                            gin::StringToV8(context->GetIsolate(),
                                            "throw new Error('simple');"))
            .ToLocalChecked();
    ASSERT_TRUE(script->Run(context).IsEmpty());
    ASSERT_TRUE(try_catch.HasCaught());
    handler.HandleException(context, "handled", &try_catch);

    ASSERT_TRUE(logged_error);
    EXPECT_EQ("handled: Error: simple\n    at <anonymous>:1:7", *logged_error);
  }

  logged_error.reset();

  {
    v8::TryCatch try_catch(isolate());
    v8::Local<v8::Function> throw_error_function = FunctionFromString(
        context, "(function() { throw new Error('function'); })");
    ignore_result(throw_error_function->Call(context, v8::Undefined(isolate()),
                                             0, nullptr));
    ASSERT_TRUE(try_catch.HasCaught());
    handler.HandleException(context, "handled", &try_catch);
    ASSERT_TRUE(logged_error);
    EXPECT_EQ("handled: Error: function\n    at <anonymous>:1:21",
              *logged_error);
  }

  logged_error.reset();

  {
    v8::TryCatch try_catch(isolate());
    const char kNestedCall[] =
        "function throwError() { throw new Error('nested'); }\n"
        "function callThrowError() { throwError(); }\n"
        "callThrowError()\n";
    v8::Local<v8::Script> script =
        v8::Script::Compile(context,
                            gin::StringToV8(context->GetIsolate(), kNestedCall))
            .ToLocalChecked();
    ASSERT_TRUE(script->Run(context).IsEmpty());
    ASSERT_TRUE(try_catch.HasCaught());
    handler.HandleException(context, "handled", &try_catch);
    ASSERT_TRUE(logged_error);
    const char kExpectedError[] =
        "handled: Error: nested\n"
        "    at throwError (<anonymous>:1:31)\n"
        "    at callThrowError (<anonymous>:2:29)\n"
        "    at <anonymous>:3:1";
    EXPECT_EQ(kExpectedError, *logged_error);
  }
}

}  // namespace extensions
