//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "shill/property_store.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

#include <base/stl_util.h>
#include <dbus/object_path.h>

#include "shill/error.h"
#include "shill/logging.h"
#include "shill/property_accessor.h"

using std::map;
using std::string;
using std::vector;

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kProperty;
static string ObjectID(const PropertyStore* p) { return "(property_store)"; }
}

PropertyStore::PropertyStore() {}

PropertyStore::PropertyStore(PropertyChangeCallback on_property_changed) :
    property_changed_callback_(on_property_changed) {}

PropertyStore::~PropertyStore() {}

bool PropertyStore::Contains(const string& prop) const {
  return (base::ContainsKey(bool_properties_, prop) ||
          base::ContainsKey(int16_properties_, prop) ||
          base::ContainsKey(int32_properties_, prop) ||
          base::ContainsKey(key_value_store_properties_, prop) ||
          base::ContainsKey(string_properties_, prop) ||
          base::ContainsKey(stringmap_properties_, prop) ||
          base::ContainsKey(stringmaps_properties_, prop) ||
          base::ContainsKey(strings_properties_, prop) ||
          base::ContainsKey(uint8_properties_, prop) ||
          base::ContainsKey(bytearray_properties_, prop) ||
          base::ContainsKey(uint16_properties_, prop) ||
          base::ContainsKey(uint16s_properties_, prop) ||
          base::ContainsKey(uint32_properties_, prop) ||
          base::ContainsKey(uint64_properties_, prop) ||
          base::ContainsKey(rpc_identifier_properties_, prop) ||
          base::ContainsKey(rpc_identifiers_properties_, prop));
}

bool PropertyStore::SetAnyProperty(const string& name,
                                   const brillo::Any& value,
                                   Error* error) {
  bool ret = false;
  if (value.IsTypeCompatible<bool>()) {
    ret = SetBoolProperty(name, value.Get<bool>(), error);
  } else if (value.IsTypeCompatible<uint8_t>()) {
    ret = SetUint8Property(name, value.Get<uint8_t>(), error);
  } else if (value.IsTypeCompatible<int16_t>()) {
    ret = SetInt16Property(name, value.Get<int16_t>(), error);
  } else if (value.IsTypeCompatible<int32_t>()) {
    ret = SetInt32Property(name, value.Get<int32_t>(), error);
  } else if (value.IsTypeCompatible<dbus::ObjectPath>()) {
    ret = SetStringProperty(name, value.Get<dbus::ObjectPath>().value(), error);
  } else if (value.IsTypeCompatible<string>()) {
    ret = SetStringProperty(name, value.Get<string>(), error);
  } else if (value.IsTypeCompatible<Stringmap>()) {
    ret = SetStringmapProperty(name, value.Get<Stringmap>(), error);
  } else if (value.IsTypeCompatible<Stringmaps>()) {
    SLOG(nullptr, 1) << " can't yet handle setting type "
                     << value.GetUndecoratedTypeName();
    error->Populate(Error::kInternalError);
  } else if (value.IsTypeCompatible<Strings>()) {
    ret = SetStringsProperty(name, value.Get<Strings>(), error);
  } else if (value.IsTypeCompatible<ByteArray>()) {
    ret = SetByteArrayProperty(name, value.Get<ByteArray>(), error);
  } else if (value.IsTypeCompatible<uint16_t>()) {
    ret = SetUint16Property(name, value.Get<uint16_t>(), error);
  } else if (value.IsTypeCompatible<Uint16s>()) {
    ret = SetUint16sProperty(name, value.Get<Uint16s>(), error);
  } else if (value.IsTypeCompatible<uint32_t>()) {
    ret = SetUint32Property(name, value.Get<uint32_t>(), error);
  } else if (value.IsTypeCompatible<uint64_t>()) {
    ret = SetUint64Property(name, value.Get<uint64_t>(), error);
  } else if (value.IsTypeCompatible<brillo::VariantDictionary>()) {
    KeyValueStore store;
    KeyValueStore::ConvertFromVariantDictionary(
        value.Get<brillo::VariantDictionary>(), &store);
    ret = SetKeyValueStoreProperty(name, store, error);
  } else {
    NOTREACHED() << " unknown type: " << value.GetUndecoratedTypeName();
    error->Populate(Error::kInternalError);
  }
  return ret;
}

bool PropertyStore::SetProperties(const brillo::VariantDictionary& in,
                                  Error* error) {
  for (const auto& kv : in) {
    if (!SetAnyProperty(kv.first, kv.second, error)) {
      return false;
    }
  }
  return true;
}

bool PropertyStore::GetProperties(brillo::VariantDictionary* out,
                                  Error* error) const {
  {
    ReadablePropertyConstIterator<bool> it = GetBoolPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<int16_t> it = GetInt16PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<int32_t> it = GetInt32PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<RpcIdentifier> it =
        GetRpcIdentifierPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(
          std::make_pair(it.Key(),
                         brillo::Any(dbus::ObjectPath(it.value()))));
    }
  }
  {
    ReadablePropertyConstIterator<RpcIdentifiers> it =
        GetRpcIdentifiersPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      vector<dbus::ObjectPath> rpc_identifiers_as_paths;
      for (const auto& path : it.value()) {
        rpc_identifiers_as_paths.push_back(dbus::ObjectPath(path));
      }
      out->insert(
          std::make_pair(it.Key(), brillo::Any(rpc_identifiers_as_paths)));
    }
  }
  {
    ReadablePropertyConstIterator<string> it = GetStringPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<Stringmap> it = GetStringmapPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<Stringmaps> it =
        GetStringmapsPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<Strings> it = GetStringsPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<uint8_t> it = GetUint8PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<ByteArray> it = GetByteArrayPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<uint16_t> it = GetUint16PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<Uint16s> it = GetUint16sPropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<uint32_t> it = GetUint32PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<uint64_t> it = GetUint64PropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      out->insert(std::make_pair(it.Key(), brillo::Any(it.value())));
    }
  }
  {
    ReadablePropertyConstIterator<KeyValueStore> it =
        GetKeyValueStorePropertiesIter();
    for ( ; !it.AtEnd(); it.Advance()) {
      brillo::VariantDictionary dict;
      KeyValueStore::ConvertToVariantDictionary(it.value(), &dict);
      out->insert(std::make_pair(it.Key(), dict));
    }
  }

  return true;
}

bool PropertyStore::GetBoolProperty(const string& name,
                                    bool* value,
                                    Error* error) const {
  return GetProperty(name, value, error, bool_properties_, "a bool");
}

bool PropertyStore::GetInt16Property(const string& name,
                                     int16_t* value,
                                     Error* error) const {
  return GetProperty(name, value, error, int16_properties_, "an int16_t");
}

bool PropertyStore::GetInt32Property(const string& name,
                                     int32_t* value,
                                     Error* error) const {
  return GetProperty(name, value, error, int32_properties_, "an int32_t");
}

bool PropertyStore::GetKeyValueStoreProperty(const string& name,
                                             KeyValueStore* value,
                                             Error* error) const {
  return GetProperty(name, value, error, key_value_store_properties_,
                     "a key value store");
}

bool PropertyStore::GetRpcIdentifierProperty(const string& name,
                                             RpcIdentifier* value,
                                             Error* error) const {
  return GetProperty(name, value, error, rpc_identifier_properties_,
                     "an rpc_identifier");
}

bool PropertyStore::GetStringProperty(const string& name,
                                      string* value,
                                      Error* error) const {
  return GetProperty(name, value, error, string_properties_, "a string");
}

bool PropertyStore::GetStringmapProperty(const string& name,
                                         Stringmap* values,
                                         Error* error) const {
  return GetProperty(name, values, error, stringmap_properties_,
                     "a string map");
}

bool PropertyStore::GetStringmapsProperty(const string& name,
                                          Stringmaps* values,
                                          Error* error) const {
  return GetProperty(name, values, error, stringmaps_properties_,
                     "a string map list");
}

bool PropertyStore::GetStringsProperty(const string& name,
                                       Strings* values,
                                       Error* error) const {
  return GetProperty(name, values, error, strings_properties_, "a string list");
}

bool PropertyStore::GetUint8Property(const string& name,
                                     uint8_t* value,
                                     Error* error) const {
  return GetProperty(name, value, error, uint8_properties_, "a uint8_t");
}

bool PropertyStore::GetByteArrayProperty(const string& name,
                                         ByteArray* value,
                                         Error *error) const {
  return GetProperty(name, value, error, bytearray_properties_, "a byte array");
}

bool PropertyStore::GetUint16Property(const string& name,
                                      uint16_t* value,
                                      Error* error) const {
  return GetProperty(name, value, error, uint16_properties_, "a uint16_t");
}

bool PropertyStore::GetUint16sProperty(const string& name,
                                       Uint16s* value,
                                       Error* error) const {
  return GetProperty(name, value, error, uint16s_properties_,
                     "a uint16_t list");
}

bool PropertyStore::GetUint32Property(const string& name,
                                      uint32_t* value,
                                      Error* error) const {
  return GetProperty(name, value, error, uint32_properties_, "a uint32_t");
}

bool PropertyStore::GetUint64Property(const string& name,
                                      uint64_t* value,
                                      Error* error) const {
  return GetProperty(name, value, error, uint64_properties_, "a uint64_t");
}

bool PropertyStore::SetBoolProperty(const string& name,
                                    bool value,
                                    Error* error) {
  return SetProperty(name, value, error, &bool_properties_, "a bool");
}

bool PropertyStore::SetInt16Property(const string& name,
                                     int16_t value,
                                     Error* error) {
  return SetProperty(name, value, error, &int16_properties_, "an int16_t");
}

bool PropertyStore::SetInt32Property(const string& name,
                                     int32_t value,
                                     Error* error) {
  return SetProperty(name, value, error, &int32_properties_, "an int32_t.");
}

bool PropertyStore::SetKeyValueStoreProperty(const string& name,
                                             const KeyValueStore& value,
                                             Error* error) {
  return SetProperty(name, value, error, &key_value_store_properties_,
                     "a key value store");
}

bool PropertyStore::SetStringProperty(const string& name,
                                      const string& value,
                                      Error* error) {
  return SetProperty(name, value, error, &string_properties_, "a string");
}

bool PropertyStore::SetStringmapProperty(const string& name,
                                         const map<string, string>& values,
                                         Error* error) {
  return SetProperty(name, values, error, &stringmap_properties_,
                     "a string map");
}

bool PropertyStore::SetStringmapsProperty(
    const string& name,
    const vector<map<string, string>>& values,
    Error* error) {
  return SetProperty(name, values, error, &stringmaps_properties_,
                     "a stringmaps");
}

bool PropertyStore::SetStringsProperty(const string& name,
                                       const vector<string>& values,
                                       Error* error) {
  return SetProperty(name, values, error, &strings_properties_,
                     "a string list");
}

bool PropertyStore::SetUint8Property(const string& name,
                                     uint8_t value,
                                     Error* error) {
  return SetProperty(name, value, error, &uint8_properties_, "a uint8_t");
}

bool PropertyStore::SetByteArrayProperty(const string& name,
                                         const ByteArray& value,
                                         Error *error) {
  return SetProperty(
      name, value, error, &bytearray_properties_, "a byte array");
}

bool PropertyStore::SetUint16Property(const string& name,
                                      uint16_t value,
                                      Error* error) {
  return SetProperty(name, value, error, &uint16_properties_, "a uint16_t");
}

bool PropertyStore::SetUint16sProperty(const string& name,
                                       const vector<uint16_t>& value,
                                       Error* error) {
  return SetProperty(name, value, error, &uint16s_properties_,
                     "a uint16_t list");
}

bool PropertyStore::SetUint32Property(const string& name,
                                      uint32_t value,
                                      Error* error) {
  return SetProperty(name, value, error, &uint32_properties_, "a uint32_t");
}

bool PropertyStore::SetUint64Property(const string& name,
                                      uint64_t value,
                                      Error* error) {
  return SetProperty(name, value, error, &uint64_properties_, "a uint64_t");
}

bool PropertyStore::SetRpcIdentifierProperty(const string& name,
                                             const RpcIdentifier& value,
                                             Error* error) {
  return SetProperty(name, value, error, &rpc_identifier_properties_,
                     "an rpc_identifier");
}

bool PropertyStore::ClearProperty(const string& name, Error* error) {
  SLOG(this, 2) << "Clearing " << name << ".";

  if (base::ContainsKey(bool_properties_, name)) {
    bool_properties_[name]->Clear(error);
  } else if (base::ContainsKey(int16_properties_, name)) {
    int16_properties_[name]->Clear(error);
  } else if (base::ContainsKey(int32_properties_, name)) {
    int32_properties_[name]->Clear(error);
  } else if (base::ContainsKey(key_value_store_properties_, name)) {
    key_value_store_properties_[name]->Clear(error);
  } else if (base::ContainsKey(string_properties_, name)) {
    string_properties_[name]->Clear(error);
  } else if (base::ContainsKey(stringmap_properties_, name)) {
    stringmap_properties_[name]->Clear(error);
  } else if (base::ContainsKey(stringmaps_properties_, name)) {
    stringmaps_properties_[name]->Clear(error);
  } else if (base::ContainsKey(strings_properties_, name)) {
    strings_properties_[name]->Clear(error);
  } else if (base::ContainsKey(uint8_properties_, name)) {
    uint8_properties_[name]->Clear(error);
  } else if (base::ContainsKey(uint16_properties_, name)) {
    uint16_properties_[name]->Clear(error);
  } else if (base::ContainsKey(uint16s_properties_, name)) {
    uint16s_properties_[name]->Clear(error);
  } else if (base::ContainsKey(uint32_properties_, name)) {
    uint32_properties_[name]->Clear(error);
  } else if (base::ContainsKey(uint64_properties_, name)) {
    uint64_properties_[name]->Clear(error);
  } else if (base::ContainsKey(rpc_identifier_properties_, name)) {
    rpc_identifier_properties_[name]->Clear(error);
  } else if (base::ContainsKey(rpc_identifiers_properties_, name)) {
    rpc_identifiers_properties_[name]->Clear(error);
  } else {
    error->Populate(
        Error::kInvalidProperty, "Property " + name + " does not exist.");
  }
  if (error->IsSuccess()) {
    if (!property_changed_callback_.is_null()) {
      property_changed_callback_.Run(name);
    }
  }
  return error->IsSuccess();
}

ReadablePropertyConstIterator<bool> PropertyStore::GetBoolPropertiesIter()
    const {
  return ReadablePropertyConstIterator<bool>(bool_properties_);
}

ReadablePropertyConstIterator<int16_t> PropertyStore::GetInt16PropertiesIter()
    const {
  return ReadablePropertyConstIterator<int16_t>(int16_properties_);
}

ReadablePropertyConstIterator<int32_t> PropertyStore::GetInt32PropertiesIter()
    const {
  return ReadablePropertyConstIterator<int32_t>(int32_properties_);
}

ReadablePropertyConstIterator<KeyValueStore>
PropertyStore::GetKeyValueStorePropertiesIter() const {
  return
      ReadablePropertyConstIterator<KeyValueStore>(key_value_store_properties_);
}

ReadablePropertyConstIterator<RpcIdentifier>
PropertyStore::GetRpcIdentifierPropertiesIter() const {
  return ReadablePropertyConstIterator<RpcIdentifier>(
      rpc_identifier_properties_);
}

ReadablePropertyConstIterator<RpcIdentifiers>
PropertyStore::GetRpcIdentifiersPropertiesIter() const {
  return ReadablePropertyConstIterator<RpcIdentifiers>(
      rpc_identifiers_properties_);
}

ReadablePropertyConstIterator<string>
PropertyStore::GetStringPropertiesIter() const {
  return ReadablePropertyConstIterator<string>(string_properties_);
}

ReadablePropertyConstIterator<Stringmap>
PropertyStore::GetStringmapPropertiesIter() const {
  return ReadablePropertyConstIterator<Stringmap>(stringmap_properties_);
}

ReadablePropertyConstIterator<Stringmaps>
PropertyStore::GetStringmapsPropertiesIter()
    const {
  return ReadablePropertyConstIterator<Stringmaps>(stringmaps_properties_);
}

ReadablePropertyConstIterator<Strings> PropertyStore::GetStringsPropertiesIter()
    const {
  return ReadablePropertyConstIterator<Strings>(strings_properties_);
}

ReadablePropertyConstIterator<uint8_t> PropertyStore::GetUint8PropertiesIter()
    const {
  return ReadablePropertyConstIterator<uint8_t>(uint8_properties_);
}

ReadablePropertyConstIterator<ByteArray>
PropertyStore::GetByteArrayPropertiesIter() const {
  return ReadablePropertyConstIterator<ByteArray>(bytearray_properties_);
}

ReadablePropertyConstIterator<uint16_t> PropertyStore::GetUint16PropertiesIter()
    const {
  return ReadablePropertyConstIterator<uint16_t>(uint16_properties_);
}

ReadablePropertyConstIterator<Uint16s> PropertyStore::GetUint16sPropertiesIter()
    const {
  return ReadablePropertyConstIterator<Uint16s>(uint16s_properties_);
}

ReadablePropertyConstIterator<uint32_t> PropertyStore::GetUint32PropertiesIter()
    const {
  return ReadablePropertyConstIterator<uint32_t>(uint32_properties_);
}

ReadablePropertyConstIterator<uint64_t> PropertyStore::GetUint64PropertiesIter()
    const {
  return ReadablePropertyConstIterator<uint64_t>(uint64_properties_);
}

void PropertyStore::RegisterBool(const string& name, bool* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bool_properties_, name))
      << "(Already registered " << name << ")";
  bool_properties_[name] = BoolAccessor(new PropertyAccessor<bool>(prop));
}

void PropertyStore::RegisterConstBool(const string& name, const bool* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bool_properties_, name))
      << "(Already registered " << name << ")";
  bool_properties_[name] = BoolAccessor(new ConstPropertyAccessor<bool>(prop));
}

void PropertyStore::RegisterWriteOnlyBool(const string& name, bool* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bool_properties_, name))
      << "(Already registered " << name << ")";
  bool_properties_[name] = BoolAccessor(
      new WriteOnlyPropertyAccessor<bool>(prop));
}

void PropertyStore::RegisterInt16(const string& name, int16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int16_properties_, name))
      << "(Already registered " << name << ")";
  int16_properties_[name] = Int16Accessor(new PropertyAccessor<int16_t>(prop));
}

void PropertyStore::RegisterConstInt16(const string& name,
                                       const int16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int16_properties_, name))
      << "(Already registered " << name << ")";
  int16_properties_[name] =
      Int16Accessor(new ConstPropertyAccessor<int16_t>(prop));
}

void PropertyStore::RegisterWriteOnlyInt16(const string& name, int16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int16_properties_, name))
      << "(Already registered " << name << ")";
  int16_properties_[name] =
      Int16Accessor(new WriteOnlyPropertyAccessor<int16_t>(prop));
}
void PropertyStore::RegisterInt32(const string& name, int32_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int32_properties_, name))
      << "(Already registered " << name << ")";
  int32_properties_[name] = Int32Accessor(new PropertyAccessor<int32_t>(prop));
}

void PropertyStore::RegisterConstInt32(const string& name,
                                       const int32_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int32_properties_, name))
      << "(Already registered " << name << ")";
  int32_properties_[name] =
      Int32Accessor(new ConstPropertyAccessor<int32_t>(prop));
}

void PropertyStore::RegisterWriteOnlyInt32(const string& name, int32_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(int32_properties_, name))
      << "(Already registered " << name << ")";
  int32_properties_[name] =
      Int32Accessor(new WriteOnlyPropertyAccessor<int32_t>(prop));
}

void PropertyStore::RegisterString(const string& name, string* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(string_properties_, name))
      << "(Already registered " << name << ")";
  string_properties_[name] = StringAccessor(new PropertyAccessor<string>(prop));
}

void PropertyStore::RegisterConstString(const string& name,
                                        const string* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(string_properties_, name))
      << "(Already registered " << name << ")";
  string_properties_[name] =
      StringAccessor(new ConstPropertyAccessor<string>(prop));
}

void PropertyStore::RegisterWriteOnlyString(const string& name, string* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(string_properties_, name))
      << "(Already registered " << name << ")";
  string_properties_[name] =
      StringAccessor(new WriteOnlyPropertyAccessor<string>(prop));
}

void PropertyStore::RegisterStringmap(const string& name, Stringmap* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmap_properties_, name))
      << "(Already registered " << name << ")";
  stringmap_properties_[name] =
      StringmapAccessor(new PropertyAccessor<Stringmap>(prop));
}

void PropertyStore::RegisterConstStringmap(const string& name,
                                           const Stringmap* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmap_properties_, name))
      << "(Already registered " << name << ")";
  stringmap_properties_[name] =
      StringmapAccessor(new ConstPropertyAccessor<Stringmap>(prop));
}

void PropertyStore::RegisterWriteOnlyStringmap(const string& name,
                                               Stringmap* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmap_properties_, name))
      << "(Already registered " << name << ")";
  stringmap_properties_[name] =
      StringmapAccessor(new WriteOnlyPropertyAccessor<Stringmap>(prop));
}

void PropertyStore::RegisterStringmaps(const string& name, Stringmaps* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmaps_properties_, name))
      << "(Already registered " << name << ")";
  stringmaps_properties_[name] =
      StringmapsAccessor(new PropertyAccessor<Stringmaps>(prop));
}

void PropertyStore::RegisterConstStringmaps(const string& name,
                                            const Stringmaps* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmaps_properties_, name))
      << "(Already registered " << name << ")";
  stringmaps_properties_[name] =
      StringmapsAccessor(new ConstPropertyAccessor<Stringmaps>(prop));
}

void PropertyStore::RegisterWriteOnlyStringmaps(const string& name,
                                                Stringmaps* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmaps_properties_, name))
      << "(Already registered " << name << ")";
  stringmaps_properties_[name] =
      StringmapsAccessor(new WriteOnlyPropertyAccessor<Stringmaps>(prop));
}

void PropertyStore::RegisterStrings(const string& name, Strings* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(strings_properties_, name))
      << "(Already registered " << name << ")";
  strings_properties_[name] =
      StringsAccessor(new PropertyAccessor<Strings>(prop));
}

void PropertyStore::RegisterConstStrings(const string& name,
                                         const Strings* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(strings_properties_, name))
      << "(Already registered " << name << ")";
  strings_properties_[name] =
      StringsAccessor(new ConstPropertyAccessor<Strings>(prop));
}

void PropertyStore::RegisterWriteOnlyStrings(const string& name,
                                             Strings* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(strings_properties_, name))
      << "(Already registered " << name << ")";
  strings_properties_[name] =
      StringsAccessor(new WriteOnlyPropertyAccessor<Strings>(prop));
}

void PropertyStore::RegisterUint8(const string& name, uint8_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint8_properties_, name))
      << "(Already registered " << name << ")";
  uint8_properties_[name] = Uint8Accessor(new PropertyAccessor<uint8_t>(prop));
}

void PropertyStore::RegisterConstUint8(const string& name,
                                       const uint8_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint8_properties_, name))
      << "(Already registered " << name << ")";
  uint8_properties_[name] =
      Uint8Accessor(new ConstPropertyAccessor<uint8_t>(prop));
}

void PropertyStore::RegisterWriteOnlyUint8(const string& name, uint8_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint8_properties_, name))
      << "(Already registered " << name << ")";
  uint8_properties_[name] =
      Uint8Accessor(new WriteOnlyPropertyAccessor<uint8_t>(prop));
}

void PropertyStore::RegisterByteArray(const string& name, ByteArray* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bytearray_properties_, name))
      << "(Already registered " << name << ")";
  bytearray_properties_[name] =
      ByteArrayAccessor(new PropertyAccessor<ByteArray>(prop));
}

void PropertyStore::RegisterConstByteArray(const string& name,
                                           const ByteArray* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bytearray_properties_, name))
      << "(Already registered " << name << ")";
  bytearray_properties_[name] =
      ByteArrayAccessor(new ConstPropertyAccessor<ByteArray>(prop));
}

void PropertyStore::RegisterWriteOnlyByteArray(const string& name,
                                               ByteArray* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(bytearray_properties_, name))
      << "(Already registered " << name << ")";
  bytearray_properties_[name] =
      ByteArrayAccessor(new WriteOnlyPropertyAccessor<ByteArray>(prop));
}

void PropertyStore::RegisterUint16(const string& name, uint16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16_properties_, name))
      << "(Already registered " << name << ")";
  uint16_properties_[name] =
      Uint16Accessor(new PropertyAccessor<uint16_t>(prop));
}

void PropertyStore::RegisterUint16s(const string& name, Uint16s* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16s_properties_, name))
      << "(Already registered " << name << ")";
  uint16s_properties_[name] =
      Uint16sAccessor(new PropertyAccessor<Uint16s>(prop));
}

void PropertyStore::RegisterUint32(const std::string& name, uint32_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint32_properties_, name))
      << "(Already registered " << name << ")";
  uint32_properties_[name] =
      Uint32Accessor(new PropertyAccessor<uint32_t>(prop));
}

void PropertyStore::RegisterConstUint32(const string& name,
                                        const uint32_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint32_properties_, name))
      << "(Already registered " << name << ")";
  uint32_properties_[name] =
      Uint32Accessor(new ConstPropertyAccessor<uint32_t>(prop));
}

void PropertyStore::RegisterConstUint16(const string& name,
                                        const uint16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16_properties_, name))
      << "(Already registered " << name << ")";
  uint16_properties_[name] =
      Uint16Accessor(new ConstPropertyAccessor<uint16_t>(prop));
}

void PropertyStore::RegisterConstUint16s(const string& name,
                                         const Uint16s* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16s_properties_, name))
      << "(Already registered " << name << ")";
  uint16s_properties_[name] =
      Uint16sAccessor(new ConstPropertyAccessor<Uint16s>(prop));
}

void PropertyStore::RegisterWriteOnlyUint16(const string& name,
                                            uint16_t* prop) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16_properties_, name))
      << "(Already registered " << name << ")";
  uint16_properties_[name] =
      Uint16Accessor(new WriteOnlyPropertyAccessor<uint16_t>(prop));
}

void PropertyStore::RegisterDerivedBool(const string& name,
                                        const BoolAccessor& accessor) {
  DCHECK(!Contains(name) || base::ContainsKey(bool_properties_, name))
      << "(Already registered " << name << ")";
  bool_properties_[name] = accessor;
}

void PropertyStore::RegisterDerivedInt32(const string& name,
                                         const Int32Accessor& accessor) {
  DCHECK(!Contains(name) || base::ContainsKey(int32_properties_, name))
      << "(Already registered " << name << ")";
  int32_properties_[name] = accessor;
}

void PropertyStore::RegisterDerivedKeyValueStore(
    const string& name,
    const KeyValueStoreAccessor& acc) {
  DCHECK(!Contains(name) ||
         base::ContainsKey(key_value_store_properties_, name))
      << "(Already registered " << name << ")";
  key_value_store_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedRpcIdentifier(
    const string& name,
    const RpcIdentifierAccessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(rpc_identifier_properties_, name))
      << "(Already registered " << name << ")";
  rpc_identifier_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedRpcIdentifiers(
    const string& name,
    const RpcIdentifiersAccessor& accessor) {
  DCHECK(!Contains(name) ||
         base::ContainsKey(rpc_identifiers_properties_, name))
      << "(Already registered " << name << ")";
  rpc_identifiers_properties_[name] = accessor;
}

void PropertyStore::RegisterDerivedString(const string& name,
                                          const StringAccessor& accessor) {
  DCHECK(!Contains(name) || base::ContainsKey(string_properties_, name))
      << "(Already registered " << name << ")";
  string_properties_[name] = accessor;
}

void PropertyStore::RegisterDerivedStrings(const string& name,
                                           const StringsAccessor& accessor) {
  DCHECK(!Contains(name) || base::ContainsKey(strings_properties_, name))
      << "(Already registered " << name << ")";
  strings_properties_[name] = accessor;
}

void PropertyStore::RegisterDerivedStringmap(const string& name,
                                             const StringmapAccessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmap_properties_, name))
      << "(Already registered " << name << ")";
  stringmap_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedStringmaps(const string& name,
                                              const StringmapsAccessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(stringmaps_properties_, name))
      << "(Already registered " << name << ")";
  stringmaps_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedUint16(const string& name,
                                          const Uint16Accessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16_properties_, name))
      << "(Already registered " << name << ")";
  uint16_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedUint64(const string& name,
                                          const Uint64Accessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(uint64_properties_, name))
      << "(Already registered " << name << ")";
  uint64_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedUint16s(const std::string& name,
                                           const Uint16sAccessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(uint16s_properties_, name))
      << "(Already registered " << name << ")";
  uint16s_properties_[name] = acc;
}

void PropertyStore::RegisterDerivedByteArray(const string& name,
                                             const ByteArrayAccessor& acc) {
  DCHECK(!Contains(name) || base::ContainsKey(bytearray_properties_, name))
      << "(Already registered " << name << ")";
  bytearray_properties_[name] = acc;
}

// private methods

template <class V>
bool PropertyStore::GetProperty(
    const string& name,
    V* value,
    Error* error,
    const map<string, std::shared_ptr<AccessorInterface<V>>>& collection,
    const string& value_type_english) const {
  SLOG(this, 2) << "Getting " << name << " as " << value_type_english
                << ".";
  typename map<string, std::shared_ptr<AccessorInterface<V>>>::const_iterator
      it = collection.find(name);
  if (it != collection.end()) {
    V val = it->second->Get(error);
    if (error->IsSuccess()) {
      *value = val;
    }
  } else {
    if (Contains(name)) {
      error->Populate(
          Error::kInvalidArguments,
          "Property " + name + " is not " + value_type_english + ".");
    } else {
      error->Populate(
          Error::kInvalidProperty, "Property " + name + " does not exist.");
    }
  }
  return error->IsSuccess();
}

template <class V>
bool PropertyStore::SetProperty(
    const string& name,
    const V& value,
    Error* error,
    map<string, std::shared_ptr<AccessorInterface<V>>>* collection,
    const string& value_type_english) {
  bool ret = false;
  SLOG(this, 2) << "Setting " << name << " as " << value_type_english
                << ".";
  if (base::ContainsKey(*collection, name)) {
    ret = (*collection)[name]->Set(value, error);
    if (ret) {
      if (!property_changed_callback_.is_null()) {
        property_changed_callback_.Run(name);
      }
    }
  } else {
    if (Contains(name)) {
      error->Populate(
          Error::kInvalidArguments,
          "Property " + name + " is not " + value_type_english + ".");
    } else {
      error->Populate(
          Error::kInvalidProperty, "Property " + name + " does not exist.");
    }
  }
  return ret;
}

}  // namespace shill
