// 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/object_schema.h"

#include <algorithm>
#include <limits>

#include <base/logging.h>
#include <base/values.h>

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

namespace buffet {

void ObjectSchema::AddProp(const std::string& name,
                           std::shared_ptr<PropType> prop) {
  properties_[name] = prop;
}

const PropType* ObjectSchema::GetProp(const std::string& name) const {
  auto p = properties_.find(name);
  return p != properties_.end() ? p->second.get() : nullptr;
}

std::unique_ptr<base::DictionaryValue> ObjectSchema::ToJson(
    bool full_schema, ErrorPtr* error) const {
  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue);
  for (const auto& pair : properties_) {
    auto PropDef = pair.second->ToJson(full_schema, error);
    if (!PropDef)
      return std::unique_ptr<base::DictionaryValue>();
    value->SetWithoutPathExpansion(pair.first, PropDef.release());
  }
  return value;
}

bool ObjectSchema::FromJson(const base::DictionaryValue* value,
                            const ObjectSchema* object_schema,
                            ErrorPtr* error) {
  Properties properties;
  base::DictionaryValue::Iterator iter(*value);
  while (!iter.IsAtEnd()) {
    std::string name = iter.key();
    const PropType* base_schema =
        object_schema ? object_schema->GetProp(iter.key()) : nullptr;
    if (!PropFromJson(iter.key(), iter.value(), base_schema, &properties,
                      error))
      return false;
    iter.Advance();
  }
  properties_ = std::move(properties);
  return true;
}

static std::unique_ptr<PropType> CreatePropType(const std::string& type_name,
                                                const std::string& prop_name,
                                                ErrorPtr* error) {
  std::unique_ptr<PropType> prop;
  ValueType type;
  if (PropType::GetTypeFromTypeString(type_name, &type))
    prop = PropType::Create(type);
  if (!prop) {
    Error::AddToPrintf(error, errors::commands::kDomain,
                       errors::commands::kUnknownType,
                       "Unknown type %s for parameter %s",
                       type_name.c_str(), prop_name.c_str());
  }
  return prop;
}

static bool ErrorInvalidTypeInfo(const std::string& prop_name,
                                 ErrorPtr* error) {
  Error::AddToPrintf(error, errors::commands::kDomain,
                     errors::commands::kNoTypeInfo,
                     "Unable to determine parameter type for %s",
                     prop_name.c_str());
  return false;
}

bool ObjectSchema::PropFromJson(const std::string& prop_name,
                                const base::Value& value,
                                const PropType* base_schema,
                                Properties* properties,
                                ErrorPtr* error) const {
  if (value.IsType(base::Value::TYPE_STRING)) {
    // A string value is a short-hand object specification and provides
    // the parameter type.
    return PropFromJsonString(prop_name, value, base_schema, properties,
                              error);
  } else if (value.IsType(base::Value::TYPE_LIST)) {
    // One of the enumerated types.
    return PropFromJsonArray(prop_name, value, base_schema, properties,
                             error);
  } else if (value.IsType(base::Value::TYPE_DICTIONARY)) {
    // Full parameter definition.
    return PropFromJsonObject(prop_name, value, base_schema, properties,
                              error);
  }
  Error::AddToPrintf(error, errors::commands::kDomain,
                     errors::commands::kInvalidPropDef,
                     "Invalid parameter definition for %s", prop_name.c_str());
  return false;
}

bool ObjectSchema::PropFromJsonString(const std::string& prop_name,
                                      const base::Value& value,
                                      const PropType* base_schema,
                                      Properties* properties,
                                      ErrorPtr* error) const {
  std::string type_name;
  CHECK(value.GetAsString(&type_name)) << "Unable to get string value";
  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
  if (!prop)
    return false;
  base::DictionaryValue empty;
  if (!prop->FromJson(&empty, base_schema, error))
    return false;
  properties->insert(std::make_pair(prop_name, std::move(prop)));
  return true;
}

static std::string DetectArrayType(const base::ListValue* list,
                                   const PropType* base_schema) {
  std::string type_name;
  if (base_schema) {
    type_name = base_schema->GetTypeAsString();
  } else if (list->GetSize() > 0) {
    const base::Value* first_element = nullptr;
    if (list->Get(0, &first_element)) {
      switch (first_element->GetType()) {
      case base::Value::TYPE_BOOLEAN:
        type_name = PropType::GetTypeStringFromType(ValueType::Boolean);
        break;
      case base::Value::TYPE_INTEGER:
        type_name = PropType::GetTypeStringFromType(ValueType::Int);
        break;
      case base::Value::TYPE_DOUBLE:
        type_name = PropType::GetTypeStringFromType(ValueType::Double);
        break;
      case base::Value::TYPE_STRING:
        type_name = PropType::GetTypeStringFromType(ValueType::String);
        break;
      case base::Value::TYPE_DICTIONARY:
        type_name = PropType::GetTypeStringFromType(ValueType::Object);
        break;
      default:
        // The rest are unsupported.
        break;
      }
    }
  }
  return type_name;
}

bool ObjectSchema::PropFromJsonArray(const std::string& prop_name,
                                     const base::Value& value,
                                     const PropType* base_schema,
                                     Properties* properties,
                                     ErrorPtr* error) const {
  const base::ListValue* list = nullptr;
  CHECK(value.GetAsList(&list)) << "Unable to get array value";
  std::string type_name = DetectArrayType(list, base_schema);
  if (type_name.empty())
    return ErrorInvalidTypeInfo(prop_name, error);
  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
  if (!prop)
    return false;
  base::DictionaryValue array_object;
  array_object.SetWithoutPathExpansion(commands::attributes::kOneOf_Enum,
                                       list->DeepCopy());
  if (!prop->FromJson(&array_object, base_schema, error))
    return false;
  properties->insert(std::make_pair(prop_name, std::move(prop)));
  return true;
}

static std::string DetectObjectType(const base::DictionaryValue* dict,
                                    const PropType* base_schema) {
  bool has_min_max = dict->HasKey(commands::attributes::kNumeric_Min) ||
                     dict->HasKey(commands::attributes::kNumeric_Max);

  // Here we are trying to "detect the type and read in the object based on
  // the deduced type". Later, we'll verify that this detected type matches
  // the expectation of the base schema, if applicable, to make sure we are not
  // changing the expected type. This makes the vendor-side (re)definition of
  // standard and custom commands behave exactly the same.
  // The only problem with this approach was the double-vs-int types.
  // If the type is meant to be a double we want to allow its definition as
  // "min:0, max:0" instead of just forcing it to be only "min:0.0, max:0.0".
  // If we have "minimum" or "maximum", and we have a Double schema object,
  // treat this object as a Double (even if both min and max are integers).
  if (has_min_max && base_schema && base_schema->GetType() == ValueType::Double)
    return PropType::GetTypeStringFromType(ValueType::Double);

  // If we have at least one "minimum" or "maximum" that is Double,
  // it's a Double.
  const base::Value* value = nullptr;
  if (dict->Get(commands::attributes::kNumeric_Min, &value) &&
      value->IsType(base::Value::TYPE_DOUBLE))
    return PropType::GetTypeStringFromType(ValueType::Double);
  if (dict->Get(commands::attributes::kNumeric_Max, &value) &&
      value->IsType(base::Value::TYPE_DOUBLE))
    return PropType::GetTypeStringFromType(ValueType::Double);

  // If we have "minimum" or "maximum", it's an Integer.
  if (has_min_max)
    return PropType::GetTypeStringFromType(ValueType::Int);

  // If we have "minLength" or "maxLength", it's a String.
  if (dict->HasKey(commands::attributes::kString_MinLength) ||
      dict->HasKey(commands::attributes::kString_MaxLength))
    return PropType::GetTypeStringFromType(ValueType::String);

  // If we have "properties", it's an object.
  if (dict->HasKey(commands::attributes::kObject_Properties))
    return PropType::GetTypeStringFromType(ValueType::Object);

  // If we have "enum", it's an array. Detect type from array elements.
  const base::ListValue* list = nullptr;
  if (dict->GetListWithoutPathExpansion(
      commands::attributes::kOneOf_Enum, &list))
    return DetectArrayType(list, base_schema);

  return std::string();
}

bool ObjectSchema::PropFromJsonObject(const std::string& prop_name,
                                      const base::Value& value,
                                      const PropType* base_schema,
                                      Properties* properties,
                                      ErrorPtr* error) const {
  const base::DictionaryValue* dict = nullptr;
  CHECK(value.GetAsDictionary(&dict)) << "Unable to get dictionary value";
  std::string type_name;
  if (dict->HasKey(commands::attributes::kType)) {
    if (!dict->GetString(commands::attributes::kType, &type_name))
      return ErrorInvalidTypeInfo(prop_name, error);
  } else {
    type_name = DetectObjectType(dict, base_schema);
  }
  if (type_name.empty()) {
    if (!base_schema)
      return ErrorInvalidTypeInfo(prop_name, error);
    type_name = base_schema->GetTypeAsString();
  }
  std::unique_ptr<PropType> prop = CreatePropType(type_name, prop_name, error);
  if (!prop || !prop->FromJson(dict, base_schema, error))
    return false;
  properties->insert(std::make_pair(prop_name, std::move(prop)));
  return true;
}

}  // namespace buffet
