// Copyright 2015 The Weave 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 LIBWEAVE_SRC_COMMANDS_PROP_CONSTRAINTS_H_
#define LIBWEAVE_SRC_COMMANDS_PROP_CONSTRAINTS_H_

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

#include <base/macros.h>
#include <base/values.h>
#include <weave/error.h>

#include "src/commands/prop_values.h"
#include "src/commands/schema_constants.h"
#include "src/commands/schema_utils.h"
#include "src/string_utils.h"

namespace weave {

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, ErrorPtr* error) const = 0;

  // Makes a full copy of this Constraint instance.
  virtual std::unique_ptr<Constraint> Clone() const = 0;

  // Makes a copy of the constraint object, marking all the attributes
  // as inherited from the original definition.
  virtual std::unique_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 void AddToJsonDict(base::DictionaryValue* dict,
                             bool overridden_only) 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() 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(ErrorPtr* error,
                                  const std::string& val,
                                  const std::string& limit);
  static bool ReportErrorGreaterThan(ErrorPtr* error,
                                     const std::string& val,
                                     const std::string& limit);

  static bool ReportErrorNotOneOf(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() const override {
    return TypedValueToJson(limit_.value);
  }

  // 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 override { return ConstraintType::Min; }

  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value, ErrorPtr* error) const override {
    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
    if (v < this->limit_.value) {
      return this->ReportErrorLessThan(error, std::to_string(v),
                                       std::to_string(this->limit_.value));
    }
    return true;
  }

  // Implementation of Constraint::Clone().
  std::unique_ptr<Constraint> Clone() const override {
    return std::unique_ptr<Constraint>{new ConstraintMin{this->limit_}};
  }

  // Implementation of Constraint::CloneAsInherited().
  std::unique_ptr<Constraint> CloneAsInherited() const override {
    return std::unique_ptr<Constraint>{new 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 override { return ConstraintType::Max; }

  // Implementation of Constraint::Validate().
  bool Validate(const PropValue& value, ErrorPtr* error) const override {
    const T& v = static_cast<const TypedValueBase<T>&>(value).GetValue();
    if (v > this->limit_.value)
      return this->ReportErrorGreaterThan(error, std::to_string(v),
                                          std::to_string(this->limit_.value));
    return true;
  }

  // Implementation of Constraint::Clone().
  std::unique_ptr<Constraint> Clone() const override {
    return std::unique_ptr<Constraint>{new ConstraintMax{this->limit_}};
  }

  // Implementation of Constraint::CloneAsInherited().
  std::unique_ptr<Constraint> CloneAsInherited() const override {
    return std::unique_ptr<Constraint>{new 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() 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, ErrorPtr* error) const override;

  // Implementation of Constraint::Clone().
  std::unique_ptr<Constraint> Clone() const override;

  // Implementation of Constraint::CloneAsInherited().
  std::unique_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, ErrorPtr* error) const override;

  // Implementation of Constraint::Clone().
  std::unique_ptr<Constraint> Clone() const override;

  // Implementation of Constraint::CloneAsInherited().
  std::unique_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.
class ConstraintOneOf : public Constraint {
 public:
  explicit ConstraintOneOf(InheritableAttribute<ValueVector> set);
  explicit ConstraintOneOf(ValueVector 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, ErrorPtr* error) const override;

  // Implementation of Constraint::Clone().
  std::unique_ptr<Constraint> Clone() const override;

  // Implementation of Constraint::CloneAsInherited().
  std::unique_ptr<Constraint> CloneAsInherited() const override;

  // Implementation of Constraint::ToJson().
  std::unique_ptr<base::Value> ToJson() const override;

  // Implementation of Constraint::GetDictKey().
  const char* GetDictKey() const override;

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

 private:
  DISALLOW_COPY_AND_ASSIGN(ConstraintOneOf);
};

}  // namespace weave

#endif  // LIBWEAVE_SRC_COMMANDS_PROP_CONSTRAINTS_H_
