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

#include "src/states/state_package.h"

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

#include "src/commands/prop_types.h"
#include "src/commands/prop_values.h"
#include "src/commands/schema_utils.h"
#include "src/states/error_codes.h"

namespace weave {

StatePackage::StatePackage(const std::string& name) : name_(name) {}

bool StatePackage::AddSchemaFromJson(const base::DictionaryValue* json,
                                     ErrorPtr* error) {
  ObjectSchema schema;
  if (!schema.FromJson(json, nullptr, error))
    return false;

  // Scan first to make sure we have no property redefinitions.
  for (const auto& pair : schema.GetProps()) {
    if (types_.GetProp(pair.first)) {
      Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
                         errors::state::kPropertyRedefinition,
                         "State property '%s.%s' is already defined",
                         name_.c_str(), pair.first.c_str());
      return false;
    }
  }

  // Now move all the properties to |types_| object.
  for (const auto& pair : schema.GetProps()) {
    types_.AddProp(pair.first, pair.second->Clone());
    // Create default value for this state property.
    values_.emplace(pair.first, pair.second->CreateDefaultValue());
  }

  return true;
}

bool StatePackage::AddValuesFromJson(const base::DictionaryValue* json,
                                     ErrorPtr* error) {
  for (base::DictionaryValue::Iterator it(*json); !it.IsAtEnd(); it.Advance()) {
    if (!SetPropertyValue(it.key(), it.value(), error))
      return false;
  }
  return true;
}

std::unique_ptr<base::DictionaryValue> StatePackage::GetValuesAsJson() const {
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
  for (const auto& pair : values_) {
    auto value = pair.second->ToJson();
    CHECK(value);
    dict->SetWithoutPathExpansion(pair.first, value.release());
  }
  return dict;
}

std::unique_ptr<base::Value> StatePackage::GetPropertyValue(
    const std::string& property_name,
    ErrorPtr* error) const {
  auto it = values_.find(property_name);
  if (it == values_.end()) {
    Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
                       errors::state::kPropertyNotDefined,
                       "State property '%s.%s' is not defined", name_.c_str(),
                       property_name.c_str());
    return nullptr;
  }

  return it->second->ToJson();
}

bool StatePackage::SetPropertyValue(const std::string& property_name,
                                    const base::Value& value,
                                    ErrorPtr* error) {
  auto it = values_.find(property_name);
  if (it == values_.end()) {
    Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
                       errors::state::kPropertyNotDefined,
                       "State property '%s.%s' is not defined", name_.c_str(),
                       property_name.c_str());
    return false;
  }
  auto new_value = it->second->GetPropType()->CreatePropValue(value, error);
  if (!new_value)
    return false;
  it->second = std::move(new_value);
  return true;
}

}  // namespace weave
