// Copyright 2014 The Chromium OS 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 BUFFET_COMMANDS_SCHEMA_UTILS_H_
#define BUFFET_COMMANDS_SCHEMA_UTILS_H_

#include <limits>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

#include <base/values.h>
#include <chromeos/any.h>
#include <chromeos/errors/error.h>
#include <chromeos/variant_dictionary.h>

namespace buffet {

class PropType;
class PropValue;
class ObjectSchema;
class ObjectValue;

namespace native_types {
// C++ representation of object values.
using Object = std::map<std::string, std::shared_ptr<const PropValue>>;
}  // namespace native_types
// Converts an object to string.
std::string ToString(const native_types::Object& obj);

// InheritableAttribute class is used for specifying various command parameter
// attributes that can be inherited from a base (parent) schema.
// The |value| still specifies the actual attribute values, whether it
// is inherited or overridden, while |is_inherited| can be used to identify
// if the attribute was inherited (true) or overridden (false).
template<typename T>
class InheritableAttribute {
 public:
  InheritableAttribute() = default;
  explicit InheritableAttribute(T val)
      : value(std::move(val)), is_inherited(true) {}
  InheritableAttribute(T val, bool inherited)
      : value(std::move(val)), is_inherited(inherited) {}
  T value{};
  bool is_inherited{true};
};

// A bunch of helper function to create base::Value for specific C++ classes,
// including vectors of types. These are used in template classes below
// to simplify specialization logic.
std::unique_ptr<base::Value> TypedValueToJson(bool value,
                                              chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(int value,
                                              chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(double value,
                                              chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(const std::string& value,
                                              chromeos::ErrorPtr* error);
std::unique_ptr<base::Value> TypedValueToJson(const native_types::Object& value,
                                              chromeos::ErrorPtr* error);
template<typename T>
std::unique_ptr<base::Value> TypedValueToJson(const std::vector<T>& values,
                                              chromeos::ErrorPtr* error) {
  std::unique_ptr<base::ListValue> list(new base::ListValue);
  for (const auto& v : values) {
    auto json = TypedValueToJson(v, error);
    if (!json)
      return std::unique_ptr<base::Value>();
    list->Append(json.release());
  }
  return std::move(list);
}

// Similarly to TypedValueToJson() function above, the following overloaded
// helper methods allow to extract specific C++ data types from base::Value.
// Also used in template classes below to simplify specialization logic.
bool TypedValueFromJson(const base::Value* value_in,
                        const PropType* type,
                        bool* value_out,
                        chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
                        const PropType* type,
                        int* value_out,
                        chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
                        const PropType* type,
                        double* value_out,
                        chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
                        const PropType* type,
                        std::string* value_out,
                        chromeos::ErrorPtr* error);
bool TypedValueFromJson(const base::Value* value_in,
                        const PropType* type,
                        native_types::Object* value_out,
                        chromeos::ErrorPtr* error);

bool operator==(const native_types::Object& obj1,
                const native_types::Object& obj2);

// CompareValue is a helper function to help with implementing EqualsTo operator
// for various data types. For most scalar types it is using operator==(),
// however, for floating point values, rounding errors in binary representation
// of IEEE floats/doubles can cause straight == comparison to fail for seemingly
// equivalent values. For these, use approximate comparison with the error
// margin equal to the epsilon value defined for the corresponding data type.
// This is used when looking up values for implementation of OneOf constraints
// which should work reliably for floating points also ("number" type).

// Compare exact types using ==.
template<typename T>
inline typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
CompareValue(const T& v1, const T& v2) {
  return v1 == v2;
}

// Compare non-exact types (such as double) using precision margin (epsilon).
template<typename T>
inline typename std::enable_if<std::is_floating_point<T>::value, bool>::type
CompareValue(const T& v1, const T& v2) {
  return std::abs(v1 - v2) <= std::numeric_limits<T>::epsilon();
}

// Converts PropValue to Any in a format understood by D-Bus data serialization.
// Has special handling for Object types where native_types::Object are
// converted to chromeos::VariantDictionary.
chromeos::Any PropValueToDBusVariant(const PropValue* value);
// Converts native_types::Object to chromeos::VariantDictionary
// with proper conversion of all nested properties.
chromeos::VariantDictionary
ObjectToDBusVariant(const native_types::Object& object);
// Converts D-Bus variant to PropValue.
// Has special handling for Object types where chromeos::VariantDictionary
// is converted to native_types::Object.
std::unique_ptr<const PropValue> PropValueFromDBusVariant(
    const PropType* type,
    const chromeos::Any& value,
    chromeos::ErrorPtr* error);
// Converts D-Bus variant to ObjectValue.
bool ObjectFromDBusVariant(const ObjectSchema* object_schema,
                           const chromeos::VariantDictionary& dict,
                           native_types::Object* obj,
                           chromeos::ErrorPtr* error);

}  // namespace buffet

#endif  // BUFFET_COMMANDS_SCHEMA_UTILS_H_
