// 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)) {
    Error::AddToPrintf(error, errors::commands::kDomain,
                       errors::commands::kInvalidPropDef,
                       "Error in definition of property '%s'",
                       prop_name.c_str());
    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)) {
    Error::AddToPrintf(error, errors::commands::kDomain,
                       errors::commands::kInvalidPropDef,
                       "Error in definition of property '%s'",
                       prop_name.c_str());
    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)
    return false;
  if (!prop->FromJson(dict, base_schema, error)) {
    Error::AddToPrintf(error, errors::commands::kDomain,
                       errors::commands::kInvalidPropDef,
                       "Error in definition of property '%s'",
                       prop_name.c_str());
    return false;
  }
  properties->insert(std::make_pair(prop_name, std::move(prop)));
  return true;
}

}  // namespace buffet
