// 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_PROP_VALUES_H_
#define BUFFET_COMMANDS_PROP_VALUES_H_

#include <map>
#include <memory>
#include <string>

#include <chromeos/any.h>
#include <chromeos/errors/error.h>

#include "buffet/commands/schema_utils.h"

namespace base {
class Value;
class DictionaryValue;
}  // namespace base

namespace buffet {

// Enumeration to indicate supported command parameter types.
enum class ValueType {
  Int,
  Double,
  String,
  Boolean,
  Object
};

class PropValue;
class IntValue;
class DoubleValue;
class StringValue;
class BooleanValue;
class ObjectValue;

class PropType;

// Helper methods to get the parameter type enum value for the given
// native C++ data representation.
// The generic GetValueType<T>() is undefined, however particular
// type specializations return the appropriate ValueType.
template<typename T> ValueType GetValueType();  // Undefined.
template<>
inline ValueType GetValueType<int>() { return ValueType::Int; }
template<>
inline ValueType GetValueType<double>() { return ValueType::Double; }
template<>
inline ValueType GetValueType<std::string>() { return ValueType::String; }
template<>
inline ValueType GetValueType<bool>() { return ValueType::Boolean; }
template<>
inline ValueType GetValueType<native_types::Object>() {
  return ValueType::Object;
}

// The base class for property values.
// Concrete value classes of various types will be derived from this base.
// A property value is the actual command parameter value (or a concrete value
// that can be used in constraints and presets). The PropValue is mostly
// just parsed content of base::Value when a command is dispatched, however
// it does have some additional functionality:
//   - it has a reference to the type definition (PropType) which is used
//     when validating the value, especially for "object" types.
//   - it can be compared with another instances of values of the same type.
//     This is used to validate the values against "enum"/"one of" constraints.
class PropValue {
 public:
  explicit PropValue(const PropType* type)
      : type_(type) {}
  virtual ~PropValue() = default;

  // Gets the type of the value.
  virtual ValueType GetType() const = 0;

  // Type conversion methods. Used in lieu of RTTI and dynamic_cast<>.
  virtual IntValue* GetInt() { return nullptr; }
  virtual IntValue const* GetInt() const { return nullptr; }
  virtual DoubleValue* GetDouble() { return nullptr; }
  virtual DoubleValue const* GetDouble() const { return nullptr; }
  virtual StringValue* GetString() { return nullptr; }
  virtual StringValue const* GetString() const { return nullptr; }
  virtual BooleanValue* GetBoolean() { return nullptr; }
  virtual BooleanValue const* GetBoolean() const { return nullptr; }
  virtual ObjectValue* GetObject() { return nullptr; }
  virtual ObjectValue const* GetObject() const { return nullptr; }

  // Makes a full copy of this value class.
  virtual std::shared_ptr<PropValue> Clone() const = 0;

  // Saves the value as a JSON object.
  // If it fails, returns nullptr value and fills in the details for the
  // failure in the |error| parameter.
  virtual std::unique_ptr<base::Value> ToJson(
      chromeos::ErrorPtr* error) const = 0;
  // Parses a value from JSON.
  // If it fails, it returns false and provides additional information
  // via the |error| parameter.
  virtual bool FromJson(const base::Value* value,
                        chromeos::ErrorPtr* error) = 0;

  // Returns the contained C++ value as Any.
  virtual chromeos::Any GetValueAsAny() const = 0;

  // Return the type definition of this value.
  const PropType* GetPropType() const { return type_; }
  // Compares two values and returns true if they are equal.
  virtual bool IsEqual(const PropValue* value) const = 0;

 protected:
  const PropType* type_;  // weak pointer
};

// A helper template base class for implementing simple (non-Object) value
// classes.
template<typename Derived, typename T>
class TypedValueBase : public PropValue {
 public:
  // To help refer to this base class from derived classes, define _Base to
  // be this class.
  using _Base = TypedValueBase<Derived, T>;
  // Expose the non-default constructor of the base class.
  using PropValue::PropValue;

  // Overrides from PropValue base class.
  ValueType GetType() const override { return GetValueType<T>(); }
  std::shared_ptr<PropValue> Clone() const override {
    return std::make_shared<Derived>(*static_cast<const Derived*>(this));
  }

  std::unique_ptr<base::Value> ToJson(
      chromeos::ErrorPtr* error) const override {
    return TypedValueToJson(value_, error);
  }

  bool FromJson(const base::Value* value, chromeos::ErrorPtr* error) override {
    return TypedValueFromJson(value, GetPropType(), &value_, error);
  }

  bool IsEqual(const PropValue* value) const override {
    if (GetType() != value->GetType())
      return false;
    const _Base* value_base = static_cast<const _Base*>(value);
    return CompareValue(GetValue(), value_base->GetValue());
  }

  // Helper methods to get and set the C++ representation of the value.
  chromeos::Any GetValueAsAny() const override { return value_; }
  const T& GetValue() const { return value_; }
  void SetValue(T value) { value_ = std::move(value); }

 protected:
  T value_{};  // The value of the parameter in C++ data representation.
};

// Value of type Integer.
class IntValue final : public TypedValueBase<IntValue, int> {
 public:
  using _Base::_Base;  // Expose the custom constructor of the base class.
  IntValue* GetInt() override { return this; }
  IntValue const* GetInt() const override { return this; }
};

// Value of type Number.
class DoubleValue final : public TypedValueBase<DoubleValue, double> {
 public:
  using _Base::_Base;  // Expose the custom constructor of the base class.
  DoubleValue* GetDouble() override { return this; }
  DoubleValue const* GetDouble() const override { return this; }
};

// Value of type String.
class StringValue final : public TypedValueBase<StringValue, std::string> {
 public:
  using _Base::_Base;  // Expose the custom constructor of the base class.
  StringValue* GetString() override { return this; }
  StringValue const* GetString() const override { return this; }
};

// Value of type Boolean.
class BooleanValue final : public TypedValueBase<BooleanValue, bool> {
 public:
  using _Base::_Base;  // Expose the custom constructor of the base class.
  BooleanValue* GetBoolean() override { return this; }
  BooleanValue const* GetBoolean() const override { return this; }
};

// Value of type Object.
class ObjectValue final
    : public TypedValueBase<ObjectValue, native_types::Object> {
 public:
  using _Base::_Base;  // Expose the custom constructor of the base class.
  ObjectValue* GetObject() override { return this; }
  ObjectValue const* GetObject() const override { return this; }
};
}  // namespace buffet

#endif  // BUFFET_COMMANDS_PROP_VALUES_H_
