// Copyright 2013 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 "gin/converter.h"

#include <limits.h>
#include <stddef.h>
#include <stdint.h>

#include "base/compiler_specific.h"
#include "gin/handle.h"
#include "gin/public/isolate_holder.h"
#include "gin/test/v8_test.h"
#include "gin/wrappable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "v8/include/v8.h"

namespace gin {

using v8::Array;
using v8::Boolean;
using v8::HandleScope;
using v8::Integer;
using v8::Local;
using v8::Null;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Undefined;
using v8::Value;

typedef V8Test ConverterTest;

TEST_F(ConverterTest, Bool) {
  HandleScope handle_scope(instance_->isolate());

  EXPECT_TRUE(Converter<bool>::ToV8(instance_->isolate(), true)->StrictEquals(
      Boolean::New(instance_->isolate(), true)));
  EXPECT_TRUE(Converter<bool>::ToV8(instance_->isolate(), false)->StrictEquals(
      Boolean::New(instance_->isolate(), false)));

  struct {
    Local<Value> input;
    bool expected;
  } test_data[] = {
    { Boolean::New(instance_->isolate(), false).As<Value>(), false },
    { Boolean::New(instance_->isolate(), true).As<Value>(), true },
    { Number::New(instance_->isolate(), 0).As<Value>(), false },
    { Number::New(instance_->isolate(), 1).As<Value>(), true },
    { Number::New(instance_->isolate(), -1).As<Value>(), true },
    { Number::New(instance_->isolate(), 0.1).As<Value>(), true },
    { String::NewFromUtf8(instance_->isolate(), "").As<Value>(), false },
    { String::NewFromUtf8(instance_->isolate(), "foo").As<Value>(), true },
    { Object::New(instance_->isolate()).As<Value>(), true },
    { Null(instance_->isolate()).As<Value>(), false },
    { Undefined(instance_->isolate()).As<Value>(), false },
  };

  for (size_t i = 0; i < arraysize(test_data); ++i) {
    bool result = false;
    EXPECT_TRUE(Converter<bool>::FromV8(instance_->isolate(),
                                        test_data[i].input, &result));
    EXPECT_EQ(test_data[i].expected, result);

    result = true;
    EXPECT_TRUE(Converter<bool>::FromV8(instance_->isolate(),
                                        test_data[i].input, &result));
    EXPECT_EQ(test_data[i].expected, result);
  }
}

TEST_F(ConverterTest, Int32) {
  HandleScope handle_scope(instance_->isolate());

  int test_data_to[] = {-1, 0, 1};
  for (size_t i = 0; i < arraysize(test_data_to); ++i) {
    EXPECT_TRUE(Converter<int32_t>::ToV8(instance_->isolate(), test_data_to[i])
                    ->StrictEquals(
                          Integer::New(instance_->isolate(), test_data_to[i])));
  }

  struct {
    v8::Local<v8::Value> input;
    bool expect_success;
    int expected_result;
  } test_data_from[] = {
    { Boolean::New(instance_->isolate(), false).As<Value>(), false, 0 },
    { Boolean::New(instance_->isolate(), true).As<Value>(), false, 0 },
    { Integer::New(instance_->isolate(), -1).As<Value>(), true, -1 },
    { Integer::New(instance_->isolate(), 0).As<Value>(), true, 0 },
    { Integer::New(instance_->isolate(), 1).As<Value>(), true, 1 },
    { Number::New(instance_->isolate(), -1).As<Value>(), true, -1 },
    { Number::New(instance_->isolate(), 1.1).As<Value>(), false, 0 },
    { String::NewFromUtf8(instance_->isolate(), "42").As<Value>(), false, 0 },
    { String::NewFromUtf8(instance_->isolate(), "foo").As<Value>(), false, 0 },
    { Object::New(instance_->isolate()).As<Value>(), false, 0 },
    { Array::New(instance_->isolate()).As<Value>(), false, 0 },
    { v8::Null(instance_->isolate()).As<Value>(), false, 0 },
    { v8::Undefined(instance_->isolate()).As<Value>(), false, 0 },
  };

  for (size_t i = 0; i < arraysize(test_data_from); ++i) {
    int32_t result = std::numeric_limits<int32_t>::min();
    bool success = Converter<int32_t>::FromV8(instance_->isolate(),
                                              test_data_from[i].input, &result);
    EXPECT_EQ(test_data_from[i].expect_success, success) << i;
    if (success)
      EXPECT_EQ(test_data_from[i].expected_result, result) << i;
  }
}

TEST_F(ConverterTest, Vector) {
  HandleScope handle_scope(instance_->isolate());

  std::vector<int> expected;
  expected.push_back(-1);
  expected.push_back(0);
  expected.push_back(1);

  auto js_array =
      Converter<std::vector<int>>::ToV8(instance_->isolate(), expected)
          .As<Array>();
  EXPECT_EQ(3u, js_array->Length());
  for (size_t i = 0; i < expected.size(); ++i) {
    EXPECT_TRUE(Integer::New(instance_->isolate(), expected[i])
                    ->StrictEquals(js_array->Get(static_cast<int>(i))));
  }
}

TEST_F(ConverterTest, VectorOfVectors) {
  HandleScope handle_scope(instance_->isolate());

  std::vector<std::vector<int>> vector_of_vectors = {
      {1, 2, 3}, {4, 5, 6},
  };

  v8::Local<v8::Value> v8_value =
      ConvertToV8(instance_->isolate(), vector_of_vectors);
  std::vector<std::vector<int>> out_value;
  ASSERT_TRUE(ConvertFromV8(instance_->isolate(), v8_value, &out_value));
  EXPECT_THAT(out_value, testing::ContainerEq(vector_of_vectors));
}

namespace {

class MyObject : public Wrappable<MyObject> {
 public:
  static WrapperInfo kWrapperInfo;

  static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
    return CreateHandle(isolate, new MyObject());
  }
};

WrapperInfo MyObject::kWrapperInfo = {kEmbedderNativeGin};

}  // namespace

TEST_F(ConverterTest, VectorOfWrappables) {
  v8::Isolate* isolate = instance_->isolate();
  v8::HandleScope handle_scope(isolate);

  Handle<MyObject> obj = MyObject::Create(isolate);
  std::vector<MyObject*> vector = {obj.get()};
  v8::MaybeLocal<v8::Value> maybe = ConvertToV8(isolate, vector);
  v8::Local<v8::Value> array;
  ASSERT_TRUE(maybe.ToLocal(&array));
  v8::Local<v8::Value> array2;
  ASSERT_TRUE(TryConvertToV8(isolate, vector, &array2));

  std::vector<MyObject*> out_value;
  ASSERT_TRUE(ConvertFromV8(isolate, array, &out_value));
  EXPECT_THAT(out_value, testing::ContainerEq(vector));
  std::vector<MyObject*> out_value2;
  ASSERT_TRUE(ConvertFromV8(isolate, array2, &out_value2));
  EXPECT_THAT(out_value2, testing::ContainerEq(vector));
}

}  // namespace gin
