// 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_CONSTRAINTS_H_
#define BUFFET_COMMANDS_PROP_CONSTRAINTS_H_

#include <string>
#include <type_traits>
#include <vector>

#include <base/macros.h>
#include <base/values.h>
#include <chromeos/errors/error.h>
#include <chromeos/strings/string_utils.h>

#include "buffet/commands/prop_values.h"
#include "buffet/commands/schema_constants.h"
#include "buffet/commands/schema_utils.h"

namespace buffet {

enum class ConstraintType {
  Min,
  Max,
  StringLengthMin,
  StringLengthMax,
  OneOf
};

// Abstract base class for all parameter constraints. Many constraints are
// type-dependent. Thus, a numeric parameter could have "minimum" and/or
// "maximum" constraints specified. Some constraints, such as "OneOf" apply to
// any data type.
class Constraint {
 public:
  Constraint() = default;
  virtual ~Constraint();

  // Gets the constraint type.
  virtual ConstraintType GetType() const = 0;
  // Checks if any of the constraint properties/attributes are overridden
  // from their base schema definition. If the constraint is inherited, then
  // it will not be written to JSON when saving partial schema.
  virtual bool HasOverriddenAttributes() const = 0;
  // Validates a parameter against the constraint. Returns true if parameter
  // value satisfies the constraint, otherwise fills the optional |error| with
  // the details for the failure.
  virtual bool Validate(const PropValue& value,
                        chromeos::ErrorPtr* error) const = 0;
  // Makes a copy of the constraint object, marking all the attributes
  // as inherited from the original definition.
  virtual std::shared_ptr<Constraint> CloneAsInherited() const = 0;
  // Saves the constraint into the specified JSON |dict| object, representing
  // the object schema. If |overridden_only| is set to true, then the
  // inherited constraints will not be added to the schema object.
  virtual bool AddToJsonDict(base::DictionaryValue* dict, bool overridden_only,
                             chromeos::ErrorPtr* error) const;
  // Saves the value of constraint to JSON value. E.g., if the numeric
  // constraint was defined as {"minimum":20} this will create a JSON value
  // of 20. The current design implies that each constraint has one value
  // only. If this assumption changes, this interface needs to be updated
  // accordingly.
  virtual std::unique_ptr<base::Value> ToJson(
      chromeos::ErrorPtr* error) const = 0;
  // Overloaded by the concrete class implementation, it should return the
  // JSON object property name to store the constraint's value as.
  // E.g., if the numeric constraint was defined as {"minimum":20} this
  // method should return "minimum".
  virtual const char* GetDictKey() const = 0;

 protected:
  // Static helper methods to format common constraint validation errors.
  // They fill the |error| object with specific error message.
  // Since these functions could be used by constraint objects for various
  // data types, the values used in validation are expected to be
  // send as strings already.
  static bool ReportErrorLessThan(chromeos::ErrorPtr* error,
                                  const std::string& val,
                                  const std::string& limit);
  static bool ReportErrorGreaterThan(chromeos::ErrorPtr* error,
                                     const std::string& val,
                                     const std::string& limit);

  static bool ReportErrorNotOneOf(chromeos::ErrorPtr* error,
                                  const std::string& val,
                                  const std::vector<std::string>& values);

 private:
  DISALLOW_COPY_AND_ASSIGN(Constraint);
};

// ConstraintMinMaxBase is a base class for numeric Minimum and Maximum
// constraints.
template<typename T>
class ConstraintMinMaxBase : public Constraint {
 public:
  explicit ConstraintMinMaxBase(const InheritableAttribute<T>& limit)
      : limit_(limit) {}
  explicit ConstraintMinMaxBase(const T& limit)
      : limit_(limit) {}

  // Implementation of Constraint::HasOverriddenAttributes().
  bool HasOverriddenAttributes() const override {
    return !limit_.is_inherited;
  }

  // Implementation of Constraint::ToJson().
  std::unique_ptr<base::Value> ToJson(
      chromeos::ErrorPtr* error) const override {
    return TypedValueToJson(limit_.value, error);
  }

  // Stores the upper/lower value limit for maximum/minimum constraint.
  // |limit_.is_inherited| indicates whether the constraint is inherited
  // from base schema or overridden.
  InheritableAttribute<T> limit_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintMinMaxBase);
};

// Implementation of Minimum value constraint for Integer/Double types.
template<typename T>
class ConstraintMin : public ConstraintMinMaxBase<T> {
 public:
  explicit ConstraintMin(const InheritableAttribute<T>& limit)
      : ConstraintMinMaxBase<T>(limit) {}
  explicit ConstraintMin(const T& limit)
      : ConstraintMinMaxBase<T>(limit) {}

  // Implementation of Constraint::GetType().
  ConstraintType GetType() const { return ConstraintType::Min; }

  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value,
                chromeos::ErrorPtr* error) const override {
    T v = value.GetValueAsAny().Get<T>();
    if (v < this->limit_.value)
      return this->ReportErrorLessThan(
          error, chromeos::string_utils::ToString(v),
          chromeos::string_utils::ToString(this->limit_.value));
    return true;
  }

  // Implementation of Constraint::CloneAsInherited().
  std::shared_ptr<Constraint> CloneAsInherited() const override {
    return std::make_shared<ConstraintMin>(this->limit_.value);
  }

  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override {
    return commands::attributes::kNumeric_Min;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintMin);
};

// Implementation of Maximum value constraint for Integer/Double types.
template<typename T>
class ConstraintMax : public ConstraintMinMaxBase<T> {
 public:
  explicit ConstraintMax(const InheritableAttribute<T>& limit)
      : ConstraintMinMaxBase<T>(limit) {}
  explicit ConstraintMax(const T& limit)
      : ConstraintMinMaxBase<T>(limit) {}

  // Implementation of Constraint::GetType().
  ConstraintType GetType() const { return ConstraintType::Max; }

  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value,
                chromeos::ErrorPtr* error) const override {
    T v = value.GetValueAsAny().Get<T>();
    if (v > this->limit_.value)
      return this->ReportErrorGreaterThan(
          error, chromeos::string_utils::ToString(v),
          chromeos::string_utils::ToString(this->limit_.value));
    return true;
  }

  // Implementation of Constraint::CloneAsInherited().
  std::shared_ptr<Constraint> CloneAsInherited() const override {
    return std::make_shared<ConstraintMax>(this->limit_.value);
  }

  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override {
    return commands::attributes::kNumeric_Max;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintMax);
};

// ConstraintStringLength is a base class for Minimum/Maximum string length
// constraints, similar to ConstraintMinMaxBase of numeric types.
class ConstraintStringLength : public Constraint {
 public:
  explicit ConstraintStringLength(const InheritableAttribute<int>& limit);
  explicit ConstraintStringLength(int limit);

  // Implementation of Constraint::HasOverriddenAttributes().
  bool HasOverriddenAttributes() const override;
  // Implementation of Constraint::ToJson().
  std::unique_ptr<base::Value> ToJson(chromeos::ErrorPtr* error) const override;

  // Stores the upper/lower value limit for string length constraint.
  // |limit_.is_inherited| indicates whether the constraint is inherited
  // from base schema or overridden.
  InheritableAttribute<int> limit_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLength);
};

// Implementation of Minimum string length constraint.
class ConstraintStringLengthMin : public ConstraintStringLength {
 public:
  explicit ConstraintStringLengthMin(const InheritableAttribute<int>& limit);
  explicit ConstraintStringLengthMin(int limit);
  // Implementation of Constraint::GetType().
  ConstraintType GetType() const override {
    return ConstraintType::StringLengthMin;
  }
  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value,
                chromeos::ErrorPtr* error) const override;
  // Implementation of Constraint::CloneAsInherited().
  std::shared_ptr<Constraint> CloneAsInherited() const override;
  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override {
    return commands::attributes::kString_MinLength;
  }
 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLengthMin);
};

// Implementation of Maximum string length constraint.
class ConstraintStringLengthMax : public ConstraintStringLength {
 public:
  explicit ConstraintStringLengthMax(const InheritableAttribute<int>& limit);
  explicit ConstraintStringLengthMax(int limit);
  // Implementation of Constraint::GetType().
  ConstraintType GetType() const override {
    return ConstraintType::StringLengthMax;
  }
  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value,
                chromeos::ErrorPtr* error) const override;
  // Implementation of Constraint::CloneAsInherited().
  std::shared_ptr<Constraint> CloneAsInherited() const override;
  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override {
    return commands::attributes::kString_MaxLength;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintStringLengthMax);
};

// Implementation of OneOf constraint for different data types.
template<typename T>
class ConstraintOneOf : public Constraint {
 public:
  explicit ConstraintOneOf(const InheritableAttribute<std::vector<T>>& set)
      : set_(set) {}
  explicit ConstraintOneOf(const std::vector<T>& set)
      : set_(set) {}

  // Implementation of Constraint::GetType().
  ConstraintType GetType() const override {
    return ConstraintType::OneOf;
  }

  // Implementation of Constraint::HasOverriddenAttributes().
  bool HasOverriddenAttributes() const override {
    return !set_.is_inherited;
  }

  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value,
                chromeos::ErrorPtr* error) const override {
    using chromeos::string_utils::ToString;
    T v = value.GetValueAsAny().Get<T>();
    for (const auto& item : set_.value) {
      if (CompareValue(v, item))
        return true;
    }
    std::vector<std::string> values;
    values.reserve(set_.value.size());
    for (const auto& item : set_.value) {
      values.push_back(ToString(item));
    }
    return ReportErrorNotOneOf(error, ToString(v), values);
  }

  // Implementation of Constraint::CloneAsInherited().
  std::shared_ptr<Constraint> CloneAsInherited() const override {
    return std::make_shared<ConstraintOneOf>(set_.value);
  }

  // Implementation of Constraint::ToJson().
  std::unique_ptr<base::Value> ToJson(
      chromeos::ErrorPtr* error) const override {
    return TypedValueToJson(set_.value, error);
  }

  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override {
    return commands::attributes::kOneOf_Enum;
  }

  // Stores the list of acceptable values for the parameter.
  // |set_.is_inherited| indicates whether the constraint is inherited
  // from base schema or overridden.
  InheritableAttribute<std::vector<T>> set_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintOneOf);
};

}  // namespace buffet

#endif  // BUFFET_COMMANDS_PROP_CONSTRAINTS_H_
