// Copyright (c) 2012 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 "base/json/json_value_converter.h"

#include <memory>
#include <string>
#include <vector>

#include "base/json/json_reader.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

// Very simple messages.
struct SimpleMessage {
  enum SimpleEnum {
    FOO, BAR,
  };
  int foo;
  std::string bar;
  bool baz;
  bool bstruct;
  SimpleEnum simple_enum;
  std::vector<std::unique_ptr<int>> ints;
  std::vector<std::unique_ptr<std::string>> string_values;
  SimpleMessage() : foo(0), baz(false), bstruct(false), simple_enum(FOO) {}

  static bool ParseSimpleEnum(StringPiece value, SimpleEnum* field) {
    if (value == "foo") {
      *field = FOO;
      return true;
    }
    if (value == "bar") {
      *field = BAR;
      return true;
    }
    return false;
  }

  static bool HasFieldPresent(const base::Value* value, bool* result) {
    *result = value != nullptr;
    return true;
  }

  static bool GetValueString(const base::Value* value, std::string* result) {
    const base::DictionaryValue* dict = nullptr;
    if (!value->GetAsDictionary(&dict))
      return false;

    if (!dict->GetString("val", result))
      return false;

    return true;
  }

  static void RegisterJSONConverter(
      base::JSONValueConverter<SimpleMessage>* converter) {
    converter->RegisterIntField("foo", &SimpleMessage::foo);
    converter->RegisterStringField("bar", &SimpleMessage::bar);
    converter->RegisterBoolField("baz", &SimpleMessage::baz);
    converter->RegisterCustomField<SimpleEnum>(
        "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum);
    converter->RegisterRepeatedInt("ints", &SimpleMessage::ints);
    converter->RegisterCustomValueField<bool>("bstruct",
                                              &SimpleMessage::bstruct,
                                              &HasFieldPresent);
    converter->RegisterRepeatedCustomValue<std::string>(
        "string_values",
        &SimpleMessage::string_values,
        &GetValueString);
  }
};

// For nested messages.
struct NestedMessage {
  double foo;
  SimpleMessage child;
  std::vector<std::unique_ptr<SimpleMessage>> children;

  NestedMessage() : foo(0) {}

  static void RegisterJSONConverter(
      base::JSONValueConverter<NestedMessage>* converter) {
    converter->RegisterDoubleField("foo", &NestedMessage::foo);
    converter->RegisterNestedField("child", &NestedMessage::child);
    converter->RegisterRepeatedMessage("children", &NestedMessage::children);
  }
};

}  // namespace

TEST(JSONValueConverterTest, ParseSimpleMessage) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1,\n"
      "  \"bar\": \"bar\",\n"
      "  \"baz\": true,\n"
      "  \"bstruct\": {},\n"
      "  \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
      "  \"simple_enum\": \"foo\","
      "  \"ints\": [1, 2]"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  SimpleMessage message;
  base::JSONValueConverter<SimpleMessage> converter;
  EXPECT_TRUE(converter.Convert(*value.get(), &message));

  EXPECT_EQ(1, message.foo);
  EXPECT_EQ("bar", message.bar);
  EXPECT_TRUE(message.baz);
  EXPECT_EQ(SimpleMessage::FOO, message.simple_enum);
  EXPECT_EQ(2, static_cast<int>(message.ints.size()));
  ASSERT_EQ(2U, message.string_values.size());
  EXPECT_EQ("value_1", *message.string_values[0]);
  EXPECT_EQ("value_2", *message.string_values[1]);
  EXPECT_EQ(1, *(message.ints[0]));
  EXPECT_EQ(2, *(message.ints[1]));
}

TEST(JSONValueConverterTest, ParseNestedMessage) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1.0,\n"
      "  \"child\": {\n"
      "    \"foo\": 1,\n"
      "    \"bar\": \"bar\",\n"
      "    \"bstruct\": {},\n"
      "    \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
      "    \"baz\": true\n"
      "  },\n"
      "  \"children\": [{\n"
      "    \"foo\": 2,\n"
      "    \"bar\": \"foobar\",\n"
      "    \"bstruct\": \"\",\n"
      "    \"string_values\": [{\"val\": \"value_1\"}],"
      "    \"baz\": true\n"
      "  },\n"
      "  {\n"
      "    \"foo\": 3,\n"
      "    \"bar\": \"barbaz\",\n"
      "    \"baz\": false\n"
      "  }]\n"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  NestedMessage message;
  base::JSONValueConverter<NestedMessage> converter;
  EXPECT_TRUE(converter.Convert(*value.get(), &message));

  EXPECT_EQ(1.0, message.foo);
  EXPECT_EQ(1, message.child.foo);
  EXPECT_EQ("bar", message.child.bar);
  EXPECT_TRUE(message.child.baz);
  EXPECT_TRUE(message.child.bstruct);
  ASSERT_EQ(2U, message.child.string_values.size());
  EXPECT_EQ("value_1", *message.child.string_values[0]);
  EXPECT_EQ("value_2", *message.child.string_values[1]);

  EXPECT_EQ(2, static_cast<int>(message.children.size()));
  const SimpleMessage* first_child = message.children[0].get();
  ASSERT_TRUE(first_child);
  EXPECT_EQ(2, first_child->foo);
  EXPECT_EQ("foobar", first_child->bar);
  EXPECT_TRUE(first_child->baz);
  EXPECT_TRUE(first_child->bstruct);
  ASSERT_EQ(1U, first_child->string_values.size());
  EXPECT_EQ("value_1", *first_child->string_values[0]);

  const SimpleMessage* second_child = message.children[1].get();
  ASSERT_TRUE(second_child);
  EXPECT_EQ(3, second_child->foo);
  EXPECT_EQ("barbaz", second_child->bar);
  EXPECT_FALSE(second_child->baz);
  EXPECT_FALSE(second_child->bstruct);
  EXPECT_EQ(0U, second_child->string_values.size());
}

TEST(JSONValueConverterTest, ParseFailures) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1,\n"
      "  \"bar\": 2,\n" // "bar" is an integer here.
      "  \"baz\": true,\n"
      "  \"ints\": [1, 2]"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  SimpleMessage message;
  base::JSONValueConverter<SimpleMessage> converter;
  EXPECT_FALSE(converter.Convert(*value.get(), &message));
  // Do not check the values below.  |message| may be modified during
  // Convert() even it fails.
}

TEST(JSONValueConverterTest, ParseWithMissingFields) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1,\n"
      "  \"baz\": true,\n"
      "  \"ints\": [1, 2]"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  SimpleMessage message;
  base::JSONValueConverter<SimpleMessage> converter;
  // Convert() still succeeds even if the input doesn't have "bar" field.
  EXPECT_TRUE(converter.Convert(*value.get(), &message));

  EXPECT_EQ(1, message.foo);
  EXPECT_TRUE(message.baz);
  EXPECT_EQ(2, static_cast<int>(message.ints.size()));
  EXPECT_EQ(1, *(message.ints[0]));
  EXPECT_EQ(2, *(message.ints[1]));
}

TEST(JSONValueConverterTest, EnumParserFails) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1,\n"
      "  \"bar\": \"bar\",\n"
      "  \"baz\": true,\n"
      "  \"simple_enum\": \"baz\","
      "  \"ints\": [1, 2]"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  SimpleMessage message;
  base::JSONValueConverter<SimpleMessage> converter;
  EXPECT_FALSE(converter.Convert(*value.get(), &message));
  // No check the values as mentioned above.
}

TEST(JSONValueConverterTest, RepeatedValueErrorInTheMiddle) {
  const char normal_data[] =
      "{\n"
      "  \"foo\": 1,\n"
      "  \"bar\": \"bar\",\n"
      "  \"baz\": true,\n"
      "  \"simple_enum\": \"baz\","
      "  \"ints\": [1, false]"
      "}\n";

  std::unique_ptr<Value> value = base::JSONReader::Read(normal_data);
  SimpleMessage message;
  base::JSONValueConverter<SimpleMessage> converter;
  EXPECT_FALSE(converter.Convert(*value.get(), &message));
  // No check the values as mentioned above.
}

}  // namespace base
