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

#include "buffet/commands/prop_constraints.h"

#include <base/json/json_writer.h>

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

namespace buffet {

namespace {

// Helper function to convert a property value to string, which is used for
// error reporting.
std::string PropValueToString(const PropValue& value) {
  std::string result;
  auto json = value.ToJson(nullptr);
  if (json)
    base::JSONWriter::Write(*json, &result);
  return result;
}

}  // anonymous namespace

// Constraint ----------------------------------------------------------------
Constraint::~Constraint() {}

bool Constraint::ReportErrorLessThan(chromeos::ErrorPtr* error,
                                     const std::string& val,
                                     const std::string& limit) {
  chromeos::Error::AddToPrintf(
      error, FROM_HERE, errors::commands::kDomain,
      errors::commands::kOutOfRange,
      "Value %s is out of range. It must not be less than %s",
      val.c_str(), limit.c_str());
  return false;
}

bool Constraint::ReportErrorGreaterThan(chromeos::ErrorPtr* error,
                                        const std::string& val,
                                        const std::string& limit) {
  chromeos::Error::AddToPrintf(
      error, FROM_HERE, errors::commands::kDomain,
      errors::commands::kOutOfRange,
      "Value %s is out of range. It must not be greater than %s",
      val.c_str(), limit.c_str());
  return false;
}

bool Constraint::ReportErrorNotOneOf(chromeos::ErrorPtr* error,
                                     const std::string& val,
                                     const std::vector<std::string>& values) {
  chromeos::Error::AddToPrintf(
      error, FROM_HERE, errors::commands::kDomain,
      errors::commands::kOutOfRange,
      "Value %s is invalid. Expected one of [%s]", val.c_str(),
      chromeos::string_utils::Join(",", values).c_str());
  return false;
}

bool Constraint::AddToJsonDict(base::DictionaryValue* dict,
                               bool overridden_only,
                               chromeos::ErrorPtr* error) const {
  if (!overridden_only || HasOverriddenAttributes()) {
    auto value = ToJson(error);
    if (!value)
      return false;
    dict->SetWithoutPathExpansion(GetDictKey(), value.release());
  }
  return true;
}

// ConstraintStringLength -----------------------------------------------------
ConstraintStringLength::ConstraintStringLength(
    const InheritableAttribute<int>& limit) : limit_(limit) {}
ConstraintStringLength::ConstraintStringLength(int limit) : limit_(limit) {}

bool ConstraintStringLength::HasOverriddenAttributes() const {
  return !limit_.is_inherited;
}

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

// ConstraintStringLengthMin --------------------------------------------------
ConstraintStringLengthMin::ConstraintStringLengthMin(
    const InheritableAttribute<int>& limit) : ConstraintStringLength(limit) {}
ConstraintStringLengthMin::ConstraintStringLengthMin(int limit)
    : ConstraintStringLength(limit) {}

bool ConstraintStringLengthMin::Validate(const PropValue& value,
                                         chromeos::ErrorPtr* error) const {
  CHECK(value.GetString()) << "Expecting a string value for this constraint";
  const std::string& str = value.GetString()->GetValue();
  int length = static_cast<int>(str.size());
  if (length < limit_.value) {
    if (limit_.value == 1) {
      chromeos::Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
                             errors::commands::kOutOfRange,
                             "String must not be empty");
    } else {
      chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                                   errors::commands::kOutOfRange,
                                   "String must be at least %d characters long,"
                                   " actual length of string '%s' is %d",
                                   limit_.value, str.c_str(), length);
    }
    return false;
  }
  return true;
}

std::unique_ptr<Constraint>
ConstraintStringLengthMin::Clone() const {
  return std::unique_ptr<Constraint>{new ConstraintStringLengthMin{limit_}};
}

std::unique_ptr<Constraint>
ConstraintStringLengthMin::CloneAsInherited() const {
  return std::unique_ptr<Constraint>{
      new ConstraintStringLengthMin{limit_.value}};
}

// ConstraintStringLengthMax --------------------------------------------------
ConstraintStringLengthMax::ConstraintStringLengthMax(
    const InheritableAttribute<int>& limit) : ConstraintStringLength(limit) {}
ConstraintStringLengthMax::ConstraintStringLengthMax(int limit)
    : ConstraintStringLength(limit) {}

bool ConstraintStringLengthMax::Validate(const PropValue& value,
                                         chromeos::ErrorPtr* error) const {
  CHECK(value.GetString()) << "Expecting a string value for this constraint";
  const std::string& str = value.GetString()->GetValue();
  int length = static_cast<int>(str.size());
  if (length > limit_.value) {
    chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
                                 errors::commands::kOutOfRange,
                                 "String must be no more than %d character(s) "
                                 "long, actual length of string '%s' is %d",
                                 limit_.value, str.c_str(), length);
    return false;
  }
  return true;
}

std::unique_ptr<Constraint>
ConstraintStringLengthMax::Clone() const {
  return std::unique_ptr<Constraint>{new ConstraintStringLengthMax{limit_}};
}

std::unique_ptr<Constraint>
ConstraintStringLengthMax::CloneAsInherited() const {
  return std::unique_ptr<Constraint>{
      new ConstraintStringLengthMax{limit_.value}};
}

// ConstraintOneOf --------------------------------------------------
ConstraintOneOf::ConstraintOneOf(InheritableAttribute<native_types::Array> set)
    : set_(std::move(set)) {}
ConstraintOneOf::ConstraintOneOf(native_types::Array set)
    : set_(std::move(set)) {}

bool ConstraintOneOf::Validate(const PropValue& value,
                               chromeos::ErrorPtr* error) const {
  for (const auto& item : set_.value) {
    if (value.IsEqual(item.get()))
      return true;
  }
  std::vector<std::string> choice_list;
  choice_list.reserve(set_.value.size());
  for (const auto& item : set_.value) {
    choice_list.push_back(PropValueToString(*item));
  }
  return ReportErrorNotOneOf(error, PropValueToString(value), choice_list);
}

std::unique_ptr<Constraint> ConstraintOneOf::Clone() const {
  InheritableAttribute<native_types::Array> attr;
  attr.is_inherited = set_.is_inherited;
  attr.value.reserve(set_.value.size());
  for (const auto& prop_value : set_.value) {
    attr.value.push_back(prop_value->Clone());
  }
  return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(attr)}};
}

std::unique_ptr<Constraint> ConstraintOneOf::CloneAsInherited() const {
  native_types::Array cloned;
  cloned.reserve(set_.value.size());
  for (const auto& prop_value : set_.value) {
    cloned.push_back(prop_value->Clone());
  }
  return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(cloned)}};
}

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

const char* ConstraintOneOf::GetDictKey() const {
  return commands::attributes::kOneOf_Enum;
}

}  // namespace buffet
