/*
 * 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 "cobalt/bindings/testing/bindings_test_base.h"
#include "cobalt/bindings/testing/union_types_interface.h"

#include "testing/gtest/include/gtest/gtest.h"

using ::testing::InSequence;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::_;

namespace cobalt {
namespace bindings {
namespace testing {

namespace {
typedef InterfaceBindingsTest<UnionTypesInterface> UnionTypesBindingsTest;
}  // namespace

TEST_F(UnionTypesBindingsTest, ConvertToJS) {
  InSequence dummy;

  std::string result;
  EXPECT_CALL(test_mock(), union_property()).WillOnce(
      Return(UnionTypesInterface::UnionPropertyType(std::string("foo"))));
  EXPECT_TRUE(
      EvaluateScript("typeof test.unionProperty == \"string\";", &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(test_mock(), union_property())
      .WillOnce(Return(UnionTypesInterface::UnionPropertyType(
          make_scoped_refptr(new ArbitraryInterface()))));
  EXPECT_TRUE(EvaluateScript(
      "Object.getPrototypeOf(test.unionProperty) === "
      "ArbitraryInterface.prototype;",
      &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(test_mock(), union_property())
      .WillOnce(Return(UnionTypesInterface::UnionPropertyType(5)));
  EXPECT_TRUE(
      EvaluateScript("typeof test.unionProperty == \"number\";", &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(test_mock(), union_property())
      .WillOnce(Return(UnionTypesInterface::UnionPropertyType(true)));
  EXPECT_TRUE(
      EvaluateScript("typeof test.unionProperty == \"boolean\";", &result));
  EXPECT_STREQ("true", result.c_str());
}

TEST_F(UnionTypesBindingsTest, ConvertFromJS) {
  InSequence dummy;

  UnionTypesInterface::UnionPropertyType union_type;
  EXPECT_CALL(test_mock(), set_union_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(EvaluateScript("test.unionProperty = \"string type\";", NULL));
  ASSERT_TRUE(union_type.IsType<std::string>());
  EXPECT_STREQ("string type", union_type.AsType<std::string>().c_str());

  EXPECT_CALL(test_mock(), set_union_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(EvaluateScript("test.unionProperty = true;", NULL));
  ASSERT_TRUE(union_type.IsType<bool>());
  EXPECT_EQ(true, union_type.AsType<bool>());

  EXPECT_CALL(test_mock(), set_union_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(EvaluateScript("test.unionProperty = -17;", NULL));
  ASSERT_TRUE(union_type.IsType<int32_t>());
  EXPECT_EQ(-17, union_type.AsType<int32_t>());

  EXPECT_CALL(test_mock(), set_union_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(
      EvaluateScript("test.unionProperty = new ArbitraryInterface();", NULL));
  ASSERT_TRUE(union_type.IsType<scoped_refptr<ArbitraryInterface> >());
  EXPECT_TRUE(union_type.AsType<scoped_refptr<ArbitraryInterface> >());
}

TEST_F(UnionTypesBindingsTest, ConvertFromJSInvalid) {
  InSequence dummy;

  UnionTypesInterface::UnionBasePropertyType union_base_type;
  // Try to assign wrong interface type.
  // First assign a valid value.
  EXPECT_CALL(test_mock(), set_union_base_property(_))
      .WillOnce(SaveArg<0>(&union_base_type));
  EXPECT_TRUE(
      EvaluateScript("test.unionBaseProperty = \"string type\";", NULL));
  ASSERT_TRUE(union_base_type.IsType<std::string>());
  EXPECT_EQ("string type", union_base_type.AsType<std::string>());
  // Attempt to assign invalid value.
  EXPECT_FALSE(EvaluateScript(
      "test.unionBaseProperty = new EnumerationInterface();", NULL));
  // Check the original value was preserved.
  ASSERT_TRUE(union_base_type.IsType<std::string>());
  EXPECT_EQ("string type", union_base_type.AsType<std::string>());
}

TEST_F(UnionTypesBindingsTest, ConvertFromJSInherit) {
  InSequence dummy;

  UnionTypesInterface::UnionBasePropertyType union_base_type;
  // Assign with base.
  EXPECT_CALL(test_mock(), set_union_base_property(_))
      .WillOnce(SaveArg<0>(&union_base_type));
  EXPECT_TRUE(
      EvaluateScript("test.unionBaseProperty = new BaseInterface();", NULL));
  ASSERT_TRUE(union_base_type.IsType<scoped_refptr<BaseInterface> >());
  EXPECT_TRUE(union_base_type.AsType<scoped_refptr<BaseInterface> >());

  // Assign with derived.
  EXPECT_CALL(test_mock(), set_union_base_property(_))
      .WillOnce(SaveArg<0>(&union_base_type));
  EXPECT_TRUE(
      EvaluateScript("test.unionBaseProperty = new DerivedInterface();", NULL));
  ASSERT_TRUE(union_base_type.IsType<scoped_refptr<BaseInterface> >());
  EXPECT_TRUE(union_base_type.AsType<scoped_refptr<BaseInterface> >());
}

TEST_F(UnionTypesBindingsTest, SetNullableUnion) {
  InSequence dummy;

  UnionTypesInterface::NullableUnionPropertyType union_type;
  EXPECT_CALL(test_mock(), set_union_with_nullable_member_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(
      EvaluateScript("test.unionWithNullableMemberProperty = null;", NULL));
  EXPECT_EQ(base::nullopt, union_type);

  EXPECT_CALL(test_mock(), set_nullable_union_property(_))
      .WillOnce(SaveArg<0>(&union_type));
  EXPECT_TRUE(EvaluateScript("test.nullableUnionProperty = null;", NULL));
  EXPECT_EQ(base::nullopt, union_type);
}

TEST_F(UnionTypesBindingsTest, GetNullableUnion) {
  InSequence dummy;

  std::string result;
  EXPECT_CALL(test_mock(), union_with_nullable_member_property())
      .WillOnce(Return(base::nullopt));
  EXPECT_TRUE(
      EvaluateScript("test.unionWithNullableMemberProperty == null;", &result));
  EXPECT_STREQ("true", result.c_str());

  EXPECT_CALL(test_mock(), nullable_union_property())
      .WillOnce(Return(base::nullopt));
  EXPECT_TRUE(EvaluateScript("test.nullableUnionProperty == null;", &result));
  EXPECT_STREQ("true", result.c_str());
}

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