// 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.

#ifndef BASE_JSON_JSON_VALUE_CONVERTER_H_
#define BASE_JSON_JSON_VALUE_CONVERTER_H_

#include <stddef.h>

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

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"

// JSONValueConverter converts a JSON value into a C++ struct in a
// lightweight way.
//
// Usage:
// For real examples, you may want to refer to _unittest.cc file.
//
// Assume that you have a struct like this:
//   struct Message {
//     int foo;
//     std::string bar;
//     static void RegisterJSONConverter(
//         JSONValueConverter<Message>* converter);
//   };
//
// And you want to parse a json data into this struct.  First, you
// need to declare RegisterJSONConverter() method in your struct.
//   // static
//   void Message::RegisterJSONConverter(
//       JSONValueConverter<Message>* converter) {
//     converter->RegisterIntField("foo", &Message::foo);
//     converter->RegisterStringField("bar", &Message::bar);
//   }
//
// Then, you just instantiate your JSONValueConverter of your type and call
// Convert() method.
//   Message message;
//   JSONValueConverter<Message> converter;
//   converter.Convert(json, &message);
//
// Convert() returns false when it fails.  Here "fail" means that the value is
// structurally different from expected, such like a string value appears
// for an int field.  Do not report failures for missing fields.
// Also note that Convert() will modify the passed |message| even when it
// fails for performance reason.
//
// For nested field, the internal message also has to implement the registration
// method.  Then, just use RegisterNestedField() from the containing struct's
// RegisterJSONConverter method.
//   struct Nested {
//     Message foo;
//     static void RegisterJSONConverter(...) {
//       ...
//       converter->RegisterNestedField("foo", &Nested::foo);
//     }
//   };
//
// For repeated field, we just assume std::vector<std::unique_ptr<ElementType>>
// for its container and you can put RegisterRepeatedInt or some other types.
// Use RegisterRepeatedMessage for nested repeated fields.
//
// Sometimes JSON format uses string representations for other types such
// like enum, timestamp, or URL.  You can use RegisterCustomField method
// and specify a function to convert a std::string_view to your type.
//   bool ConvertFunc(std::string_view s, YourEnum* result) {
//     // do something and return true if succeed...
//   }
//   struct Message {
//     YourEnum ye;
//     ...
//     static void RegisterJSONConverter(...) {
//       ...
//       converter->RegsiterCustomField<YourEnum>(
//           "your_enum", &Message::ye, &ConvertFunc);
//     }
//   };

namespace base {

template <typename StructType>
class JSONValueConverter;

namespace internal {

template <typename StructType>
class FieldConverterBase {
 public:
  explicit FieldConverterBase(const std::string& path) : field_path_(path) {}
  virtual ~FieldConverterBase() = default;
  virtual bool ConvertField(const base::Value& value,
                            StructType* obj) const = 0;
  const std::string& field_path() const { return field_path_; }

 private:
  std::string field_path_;
  FieldConverterBase(const FieldConverterBase&) = delete;
  FieldConverterBase& operator=(const FieldConverterBase&) = delete;
};

template <typename FieldType>
class ValueConverter {
 public:
  virtual ~ValueConverter() = default;
  virtual bool Convert(const base::Value& value, FieldType* field) const = 0;
};

template <typename StructType, typename FieldType>
class FieldConverter : public FieldConverterBase<StructType> {
 public:
  explicit FieldConverter(const std::string& path,
                          FieldType StructType::*field,
                          ValueConverter<FieldType>* converter)
      : FieldConverterBase<StructType>(path),
        field_pointer_(field),
        value_converter_(converter) {}

  bool ConvertField(const base::Value& value, StructType* dst) const override {
    return value_converter_->Convert(value, &(dst->*field_pointer_));
  }

 private:
  FieldType StructType::*field_pointer_;
  std::unique_ptr<ValueConverter<FieldType>> value_converter_;
  FieldConverter(const FieldConverter&) = delete;
  FieldConverter& operator=(const FieldConverter&) = delete;
};

template <typename FieldType>
class BasicValueConverter;

template <>
class BasicValueConverter<int> : public ValueConverter<int> {
 public:
  BasicValueConverter() = default;

  bool Convert(const base::Value& value, int* field) const override;

 private:
  BasicValueConverter(const BasicValueConverter&) = delete;
  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
};

template <>
class BasicValueConverter<std::string> : public ValueConverter<std::string> {
 public:
  BasicValueConverter() = default;

  bool Convert(const base::Value& value, std::string* field) const override;

 private:
  BasicValueConverter(const BasicValueConverter&) = delete;
  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
};

template <>
class BasicValueConverter<std::u16string>
    : public ValueConverter<std::u16string> {
 public:
  BasicValueConverter() = default;

  bool Convert(const base::Value& value, std::u16string* field) const override;

 private:
  BasicValueConverter(const BasicValueConverter&) = delete;
  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
};

template <>
class BasicValueConverter<double> : public ValueConverter<double> {
 public:
  BasicValueConverter() = default;

  bool Convert(const base::Value& value, double* field) const override;

 private:
  BasicValueConverter(const BasicValueConverter&) = delete;
  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
};

template <>
class BasicValueConverter<bool> : public ValueConverter<bool> {
 public:
  BasicValueConverter() = default;

  bool Convert(const base::Value& value, bool* field) const override;

 private:
  BasicValueConverter(const BasicValueConverter&) = delete;
  BasicValueConverter& operator=(const BasicValueConverter&) = delete;
};

template <typename FieldType>
class ValueFieldConverter : public ValueConverter<FieldType> {
 public:
  typedef bool (*ConvertFunc)(const base::Value* value, FieldType* field);

  explicit ValueFieldConverter(ConvertFunc convert_func)
      : convert_func_(convert_func) {}

  bool Convert(const base::Value& value, FieldType* field) const override {
    return convert_func_(&value, field);
  }

 private:
  ConvertFunc convert_func_;

  ValueFieldConverter(const ValueFieldConverter&) = delete;
  ValueFieldConverter& operator=(const ValueFieldConverter&) = delete;
};

template <typename FieldType>
class CustomFieldConverter : public ValueConverter<FieldType> {
 public:
  typedef bool (*ConvertFunc)(std::string_view value, FieldType* field);

  explicit CustomFieldConverter(ConvertFunc convert_func)
      : convert_func_(convert_func) {}

  bool Convert(const base::Value& value, FieldType* field) const override {
    std::string string_value;
    return value.GetAsString(&string_value) &&
           convert_func_(string_value, field);
  }

 private:
  ConvertFunc convert_func_;

  CustomFieldConverter(const CustomFieldConverter&) = delete;
  CustomFieldConverter& operator=(const CustomFieldConverter&) = delete;
};

template <typename NestedType>
class NestedValueConverter : public ValueConverter<NestedType> {
 public:
  NestedValueConverter() = default;

  bool Convert(const base::Value& value, NestedType* field) const override {
    return converter_.Convert(value, field);
  }

 private:
  JSONValueConverter<NestedType> converter_;
  NestedValueConverter(const NestedValueConverter&) = delete;
  NestedValueConverter& operator=(const NestedValueConverter&) = delete;
};

template <typename Element>
class RepeatedValueConverter
    : public ValueConverter<std::vector<std::unique_ptr<Element>>> {
 public:
  RepeatedValueConverter() = default;

  bool Convert(const base::Value& value,
               std::vector<std::unique_ptr<Element>>* field) const override {
    const base::ListValue* list = NULL;
    if (!value.GetAsList(&list)) {
      // The field is not a list.
      return false;
    }

    field->reserve(list->GetSize());
    for (size_t i = 0; i < list->GetSize(); ++i) {
      const base::Value* element = NULL;
      if (!list->Get(i, &element))
        continue;

      std::unique_ptr<Element> e(new Element);
      if (basic_converter_.Convert(*element, e.get())) {
        field->push_back(std::move(e));
      } else {
        return false;
      }
    }
    return true;
  }

 private:
  BasicValueConverter<Element> basic_converter_;
  RepeatedValueConverter(const RepeatedValueConverter&) = delete;
  RepeatedValueConverter& operator=(const RepeatedValueConverter&) = delete;
};

template <typename NestedType>
class RepeatedMessageConverter
    : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
 public:
  RepeatedMessageConverter() = default;

  bool Convert(const base::Value& value,
               std::vector<std::unique_ptr<NestedType>>* field) const override {
    const base::ListValue* list = NULL;
    if (!value.GetAsList(&list))
      return false;

    field->reserve(list->GetSize());
    for (size_t i = 0; i < list->GetSize(); ++i) {
      const base::Value* element = NULL;
      if (!list->Get(i, &element))
        continue;

      std::unique_ptr<NestedType> nested(new NestedType);
      if (converter_.Convert(*element, nested.get())) {
        field->push_back(std::move(nested));
      } else {
        return false;
      }
    }
    return true;
  }

 private:
  JSONValueConverter<NestedType> converter_;
  RepeatedMessageConverter(const RepeatedMessageConverter&) = delete;
  RepeatedMessageConverter& operator=(const RepeatedMessageConverter&) = delete;
};

template <typename NestedType>
class RepeatedCustomValueConverter
    : public ValueConverter<std::vector<std::unique_ptr<NestedType>>> {
 public:
  typedef bool (*ConvertFunc)(const base::Value* value, NestedType* field);

  explicit RepeatedCustomValueConverter(ConvertFunc convert_func)
      : convert_func_(convert_func) {}

  bool Convert(const base::Value& value,
               std::vector<std::unique_ptr<NestedType>>* field) const override {
    const base::ListValue* list = NULL;
    if (!value.GetAsList(&list))
      return false;

    field->reserve(list->GetSize());
    for (size_t i = 0; i < list->GetSize(); ++i) {
      const base::Value* element = NULL;
      if (!list->Get(i, &element))
        continue;

      std::unique_ptr<NestedType> nested(new NestedType);
      if ((*convert_func_)(element, nested.get())) {
        field->push_back(std::move(nested));
      } else {
        return false;
      }
    }
    return true;
  }

 private:
  ConvertFunc convert_func_;
  RepeatedCustomValueConverter(const RepeatedCustomValueConverter&) = delete;
  RepeatedCustomValueConverter& operator=(const RepeatedCustomValueConverter&) =
      delete;
};

}  // namespace internal

template <class StructType>
class JSONValueConverter {
 public:
  JSONValueConverter() { StructType::RegisterJSONConverter(this); }

  void RegisterIntField(const std::string& field_name, int StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, int>>(
            field_name, field, new internal::BasicValueConverter<int>));
  }

  void RegisterStringField(const std::string& field_name,
                           std::string StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, std::string>>(
            field_name, field, new internal::BasicValueConverter<std::string>));
  }

  void RegisterStringField(const std::string& field_name,
                           std::u16string StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, std::u16string>>(
            field_name, field,
            new internal::BasicValueConverter<std::u16string>));
  }

  void RegisterBoolField(const std::string& field_name,
                         bool StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, bool>>(
            field_name, field, new internal::BasicValueConverter<bool>));
  }

  void RegisterDoubleField(const std::string& field_name,
                           double StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, double>>(
            field_name, field, new internal::BasicValueConverter<double>));
  }

  template <class NestedType>
  void RegisterNestedField(const std::string& field_name,
                           NestedType StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, NestedType>>(
            field_name, field, new internal::NestedValueConverter<NestedType>));
  }

  template <typename FieldType>
  void RegisterCustomField(const std::string& field_name,
                           FieldType StructType::*field,
                           bool (*convert_func)(std::string_view, FieldType*)) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, FieldType>>(
            field_name, field,
            new internal::CustomFieldConverter<FieldType>(convert_func)));
  }

  template <typename FieldType>
  void RegisterCustomValueField(const std::string& field_name,
                                FieldType StructType::*field,
                                bool (*convert_func)(const base::Value*,
                                                     FieldType*)) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<StructType, FieldType>>(
            field_name, field,
            new internal::ValueFieldConverter<FieldType>(convert_func)));
  }

  void RegisterRepeatedInt(
      const std::string& field_name,
      std::vector<std::unique_ptr<int>> StructType::*field) {
    fields_.push_back(std::make_unique<internal::FieldConverter<
                          StructType, std::vector<std::unique_ptr<int>>>>(
        field_name, field, new internal::RepeatedValueConverter<int>));
  }

  void RegisterRepeatedString(
      const std::string& field_name,
      std::vector<std::unique_ptr<std::string>> StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<
            StructType, std::vector<std::unique_ptr<std::string>>>>(
            field_name, field,
            new internal::RepeatedValueConverter<std::string>));
  }

  void RegisterRepeatedString(
      const std::string& field_name,
      std::vector<std::unique_ptr<std::u16string>> StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<
            StructType, std::vector<std::unique_ptr<std::u16string>>>>(
            field_name, field,
            new internal::RepeatedValueConverter<std::u16string>));
  }

  void RegisterRepeatedDouble(
      const std::string& field_name,
      std::vector<std::unique_ptr<double>> StructType::*field) {
    fields_.push_back(std::make_unique<internal::FieldConverter<
                          StructType, std::vector<std::unique_ptr<double>>>>(
        field_name, field, new internal::RepeatedValueConverter<double>));
  }

  void RegisterRepeatedBool(
      const std::string& field_name,
      std::vector<std::unique_ptr<bool>> StructType::*field) {
    fields_.push_back(std::make_unique<internal::FieldConverter<
                          StructType, std::vector<std::unique_ptr<bool>>>>(
        field_name, field, new internal::RepeatedValueConverter<bool>));
  }

  template <class NestedType>
  void RegisterRepeatedCustomValue(
      const std::string& field_name,
      std::vector<std::unique_ptr<NestedType>> StructType::*field,
      bool (*convert_func)(const base::Value*, NestedType*)) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<
            StructType, std::vector<std::unique_ptr<NestedType>>>>(
            field_name, field,
            new internal::RepeatedCustomValueConverter<NestedType>(
                convert_func)));
  }

  template <class NestedType>
  void RegisterRepeatedMessage(
      const std::string& field_name,
      std::vector<std::unique_ptr<NestedType>> StructType::*field) {
    fields_.push_back(
        std::make_unique<internal::FieldConverter<
            StructType, std::vector<std::unique_ptr<NestedType>>>>(
            field_name, field,
            new internal::RepeatedMessageConverter<NestedType>));
  }

  bool Convert(const base::Value& value, StructType* output) const {
    const DictionaryValue* dictionary_value = NULL;
    if (!value.GetAsDictionary(&dictionary_value))
      return false;

    for (size_t i = 0; i < fields_.size(); ++i) {
      const internal::FieldConverterBase<StructType>* field_converter =
          fields_[i].get();
      const base::Value* field = NULL;
      if (dictionary_value->Get(field_converter->field_path(), &field)) {
        if (!field_converter->ConvertField(*field, output)) {
          return false;
        }
      }
    }
    return true;
  }

 private:
  std::vector<std::unique_ptr<internal::FieldConverterBase<StructType>>>
      fields_;

  JSONValueConverter(const JSONValueConverter&) = delete;
  JSONValueConverter& operator=(const JSONValueConverter&) = delete;
};

}  // namespace base

#endif  // BASE_JSON_JSON_VALUE_CONVERTER_H_
