/*
 * Copyright 2015 Google Inc. 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 "base/stringprintf.h"
#include "cobalt/bindings/testing/bindings_test_base.h"
#include "cobalt/bindings/testing/exception_object_interface.h"
#include "cobalt/bindings/testing/exceptions_interface.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::NiceMock;
using ::testing::WithArg;

#define EXPECT_SUBSTRING(needle, haystack) \
  EXPECT_PRED_FORMAT2(::testing::IsSubstring, (needle), (haystack))

namespace cobalt {
namespace bindings {
namespace testing {
namespace {
typedef InterfaceBindingsTest<ExceptionsInterface> ExceptionsBindingsTest;

class SimpleExceptionSetter {
 public:
  explicit SimpleExceptionSetter(script::MessageType type) : type_(type) {}
  void FireException(script::ExceptionState* exception) {
    exception->SetSimpleException(type_);
  }

 private:
  script::MessageType type_;
};

class ExceptionObjectSetter {
 public:
  explicit ExceptionObjectSetter(
      const scoped_refptr<ExceptionObjectInterface>& exception)
      : exception_object_(exception) {}
  void FireException(script::ExceptionState* exception) {
    exception->SetException(exception_object_);
  }

 private:
  scoped_refptr<script::ScriptException> exception_object_;
};

std::string GetExceptionMessageString(script::MessageType message_type, ...) {
  va_list arguments;
  va_start(arguments, message_type);
  std::string error_string =
      base::StringPrintV(GetExceptionMessageFormat(message_type), arguments);
  va_end(arguments);
  return error_string;
}

}  // namespace

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromConstructor) {
  SimpleExceptionSetter exception_setter(script::kSimpleError);
  EXPECT_CALL(ExceptionsInterface::constructor_implementation_mock.Get(),
              Constructor(_))
      .WillOnce(
          Invoke(&exception_setter, &SimpleExceptionSetter::FireException));

  std::string result;
  EXPECT_FALSE(EvaluateScript("var foo = new ExceptionsInterface();", &result));
  EXPECT_SUBSTRING("Error", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromOperation) {
  SimpleExceptionSetter exception_setter(script::kSimpleTypeError);
  EXPECT_CALL(test_mock(), FunctionThrowsException(_)).WillOnce(
      Invoke(&exception_setter, &SimpleExceptionSetter::FireException));

  std::string result;
  EXPECT_FALSE(EvaluateScript("test.functionThrowsException();", &result));
  EXPECT_SUBSTRING("TypeError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromGetter) {
  SimpleExceptionSetter exception_setter(script::kSimpleRangeError);
  EXPECT_CALL(test_mock(), attribute_throws_exception(_)).WillOnce(
      DoAll(Invoke(&exception_setter, &SimpleExceptionSetter::FireException),
            Return(false)));

  std::string result;
  EXPECT_FALSE(
      EvaluateScript("var foo = test.attributeThrowsException;", &result));
  EXPECT_SUBSTRING("RangeError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionFromSetter) {
  SimpleExceptionSetter exception_setter(script::kSimpleReferenceError);
  EXPECT_CALL(test_mock(), set_attribute_throws_exception(_, _))
      .WillOnce(WithArg<1>(
          Invoke(&exception_setter, &SimpleExceptionSetter::FireException)));

  std::string result;
  EXPECT_FALSE(
      EvaluateScript("test.attributeThrowsException = true;", &result));
  EXPECT_SUBSTRING("ReferenceError", result.c_str());
}

TEST_F(ExceptionsBindingsTest, ThrowExceptionObject) {
  scoped_refptr<ExceptionObjectInterface> exception_object =
      make_scoped_refptr(new NiceMock<ExceptionObjectInterface>());
  ExceptionObjectSetter exception_setter(exception_object);

  InSequence in_sequence_dummy;
  EXPECT_CALL(test_mock(), FunctionThrowsException(_)).WillOnce(
      Invoke(&exception_setter, &ExceptionObjectSetter::FireException));
  EXPECT_TRUE(EvaluateScript(
      "var error = null;"
      "try { test.functionThrowsException(); }"
      "catch(e) { error = e; }",
      NULL));

  std::string result;
  EXPECT_TRUE(EvaluateScript("error instanceof Error;", &result));
  EXPECT_STREQ("true", result.c_str());
  EXPECT_TRUE(
      EvaluateScript("error instanceof ExceptionObjectInterface;", &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(*exception_object, error()).WillOnce(Return("the error"));
  EXPECT_TRUE(EvaluateScript("error.error;", &result));
  EXPECT_STREQ("the error", result.c_str());

  EXPECT_CALL(*exception_object, message()).WillOnce(Return("the message"));
  EXPECT_TRUE(EvaluateScript("error.message;", &result));
  EXPECT_STREQ("the message", result.c_str());
}

TEST_F(ExceptionsBindingsTest, GetExceptionMessageStringTest) {
  std::string error_message =
      GetExceptionMessageString(script::kWrongByteLengthMultiple, 8);
  EXPECT_STREQ("Byte length should be a multiple of 8.", error_message.c_str());
  error_message =
      GetExceptionMessageString(script::kWrongByteOffsetMultiple, 16);
  EXPECT_STREQ("Byte offset should be a multiple of 16.",
               error_message.c_str());
}

}  // namespace testing
}  // namespace bindings
}  // namespace cobalt
