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

#include <base/stl_util.h>

#include "shill/logging.h"

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

namespace shill {

KeyValueStore::KeyValueStore() {}

void KeyValueStore::Clear() {
  properties_.clear();
}

bool KeyValueStore::IsEmpty() {
  return properties_.empty();
}

void KeyValueStore::CopyFrom(const KeyValueStore& b) {
  properties_ = b.properties_;
}

bool KeyValueStore::operator==(const KeyValueStore& rhs) const {
  return properties_ == rhs.properties_;
}

bool KeyValueStore::operator!=(const KeyValueStore& rhs) const {
  return properties_ != rhs.properties_;
}

bool KeyValueStore::ContainsBool(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<bool>();
}

bool KeyValueStore::ContainsBools(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<bool>>();
}

bool KeyValueStore::ContainsByteArrays(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)
             ->second.IsTypeCompatible<vector<vector<uint8_t>>>();
}

bool KeyValueStore::ContainsInt(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<int32_t>();
}

bool KeyValueStore::ContainsInts(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<int32_t>>();
}

bool KeyValueStore::ContainsInt16(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<int16_t>();
}

bool KeyValueStore::ContainsInt64(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<int64_t>();
}

bool KeyValueStore::ContainsInt64s(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<int64_t>>();
}

bool KeyValueStore::ContainsDouble(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<double>();
}

bool KeyValueStore::ContainsDoubles(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<double>>();
}

bool KeyValueStore::ContainsKeyValueStore(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<KeyValueStore>();
}

bool KeyValueStore::ContainsRpcIdentifier(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<dbus::ObjectPath>();
}

bool KeyValueStore::ContainsRpcIdentifiers(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)
             ->second.IsTypeCompatible<vector<dbus::ObjectPath>>();
}

bool KeyValueStore::ContainsString(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<string>();
}

bool KeyValueStore::ContainsStringmap(const std::string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<Stringmap>();
}

bool KeyValueStore::ContainsStrings(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<Strings>();
}

bool KeyValueStore::ContainsUint(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<uint32_t>();
}

bool KeyValueStore::ContainsUint8(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<uint8_t>();
}

bool KeyValueStore::ContainsUint16(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<uint16_t>();
}

bool KeyValueStore::ContainsUint8s(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<uint8_t>>();
}

bool KeyValueStore::ContainsUint32s(const string& name) const {
  return base::ContainsKey(properties_, name) &&
         properties_.find(name)->second.IsTypeCompatible<vector<uint32_t>>();
}

bool KeyValueStore::Contains(const string& name) const {
  return base::ContainsKey(properties_, name);
}

bool KeyValueStore::GetBool(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<bool>())
      << "for bool property " << name;
  return it->second.Get<bool>();
}

const vector<bool>& KeyValueStore::GetBools(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<vector<bool>>())
      << "for bools property " << name;
  return it->second.Get<vector<bool>>();
}

const vector<vector<uint8_t>>& KeyValueStore::GetByteArrays(
    const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<vector<uint8_t>>>())
      << "for byte arrays property " << name;
  return it->second.Get<vector<vector<uint8_t>>>();
}

int32_t KeyValueStore::GetInt(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<int32_t>())
      << "for int property " << name;
  return it->second.Get<int32_t>();
}

const vector<int32_t>& KeyValueStore::GetInts(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<int32_t>>())
      << "for ints property " << name;
  return it->second.Get<vector<int32_t>>();
}

int16_t KeyValueStore::GetInt16(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<int16_t>())
      << "for int16 property " << name;
  return it->second.Get<int16_t>();
}

int64_t KeyValueStore::GetInt64(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<int64_t>())
      << "for int64 property " << name;
  return it->second.Get<int64_t>();
}

const vector<int64_t>& KeyValueStore::GetInt64s(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<int64_t>>())
      << "for int64s property " << name;
  return it->second.Get<vector<int64_t>>();
}

double KeyValueStore::GetDouble(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<double>())
      << "for double property " << name;
  return it->second.Get<double>();
}

const vector<double>& KeyValueStore::GetDoubles(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<double>>())
      << "for doubles property " << name;
  return it->second.Get<vector<double>>();
}

const KeyValueStore& KeyValueStore::GetKeyValueStore(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<KeyValueStore>())
      << "for key value store property " << name;
  return it->second.Get<KeyValueStore>();
}

const string& KeyValueStore::GetRpcIdentifier(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<dbus::ObjectPath>())
      << "for rpc identifier property " << name;
  return it->second.Get<dbus::ObjectPath>().value();
}

vector<string> KeyValueStore::GetRpcIdentifiers(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<dbus::ObjectPath>>())
      << "for rpc identifier property " << name;
  RpcIdentifiers ids;
  KeyValueStore::ConvertPathsToRpcIdentifiers(
      it->second.Get<vector<dbus::ObjectPath>>(), &ids);
  return ids;
}

const string& KeyValueStore::GetString(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<string>())
      << "for string property " << name;
  return it->second.Get<string>();
}

const map<string, string>& KeyValueStore::GetStringmap(
    const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<Stringmap>())
      << "for stringmap property " << name;
  return it->second.Get<Stringmap>();
}

const vector<string>& KeyValueStore::GetStrings(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<Strings>())
      << "for strings property " << name;
  return it->second.Get<Strings>();
}

uint32_t KeyValueStore::GetUint(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint32_t>())
      << "for uint32 property " << name;
  return it->second.Get<uint32_t>();
}

uint16_t KeyValueStore::GetUint16(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint16_t>())
      << "for uint16 property " << name;
  return it->second.Get<uint16_t>();
}

uint8_t KeyValueStore::GetUint8(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() && it->second.IsTypeCompatible<uint8_t>())
      << "for uint8 property " << name;
  return it->second.Get<uint8_t>();
}

const vector<uint8_t>& KeyValueStore::GetUint8s(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<uint8_t>>())
      << "for uint8s property " << name;
  return it->second.Get<vector<uint8_t>>();
}

const vector<uint32_t>& KeyValueStore::GetUint32s(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end() &&
        it->second.IsTypeCompatible<vector<uint32_t>>())
      << "for uint32s property " << name;
  return it->second.Get<vector<uint32_t>>();
}

const brillo::Any& KeyValueStore::Get(const string& name) const {
  const auto it(properties_.find(name));
  CHECK(it != properties_.end());
  return it->second;
}

void KeyValueStore::SetBool(const string& name, bool value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetBools(const string& name, const vector<bool>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetByteArrays(const string& name,
                                  const vector<vector<uint8_t>>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetInt(const string& name, int32_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetInts(const string& name, const vector<int32_t>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetInt16(const string& name, int16_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetInt64(const string& name, int64_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetInt64s(const string& name,
                              const vector<int64_t>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetDouble(const string& name, double value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetDoubles(const string& name,
                               const vector<double>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetKeyValueStore(const string& name,
                                     const KeyValueStore& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetRpcIdentifier(const string& name, const string& value) {
  properties_[name] = brillo::Any(dbus::ObjectPath(value));
}

void KeyValueStore::SetRpcIdentifiers(const string& name,
                                      const vector<string>& value) {
  vector<dbus::ObjectPath> paths;
  for (const auto& rpcid : value) {
    paths.push_back(dbus::ObjectPath(rpcid));
  }
  properties_[name] = brillo::Any(paths);
}

void KeyValueStore::SetString(const string& name, const string& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetStringmap(const string& name,
                                 const map<string, string>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetStrings(const string& name,
                               const vector<string>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetUint(const string& name, uint32_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetUint16(const string& name, uint16_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetUint8(const string& name, uint8_t value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetUint8s(const string& name,
                              const vector<uint8_t>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::SetUint32s(const string& name,
                               const vector<uint32_t>& value) {
  properties_[name] = brillo::Any(value);
}

void KeyValueStore::Set(const string& name, const brillo::Any& value) {
  properties_[name] = value;
}

void KeyValueStore::Remove(const string& name) {
  properties_.erase(name);
}

bool KeyValueStore::LookupBool(const string& name, bool default_value) const {
  const auto it(properties_.find(name));
  if (it == properties_.end()) {
    return default_value;
  }
  CHECK(it->second.IsTypeCompatible<bool>()) << "type mismatched";
  return it->second.Get<bool>();
}

int KeyValueStore::LookupInt(const string& name, int default_value) const {
  const auto it(properties_.find(name));
  if (it == properties_.end()) {
    return default_value;
  }
  CHECK(it->second.IsTypeCompatible<int32_t>()) << "type mismatched";
  return it->second.Get<int32_t>();
}

string KeyValueStore::LookupString(const string& name,
                                   const string& default_value) const {
  const auto it(properties_.find(name));
  if (it == properties_.end()) {
    return default_value;
  }
  CHECK(it->second.IsTypeCompatible<string>()) << "type mismatched";
  return it->second.Get<string>();
}

// static.
void KeyValueStore::ConvertToVariantDictionary(
    const KeyValueStore& in_store, brillo::VariantDictionary* out_dict) {
  for (const auto& key_value_pair : in_store.properties_) {
    if (key_value_pair.second.IsTypeCompatible<KeyValueStore>()) {
      // Special handling for nested KeyValueStore (convert it to
      // nested brillo::VariantDictionary).
      brillo::VariantDictionary dict;
      ConvertToVariantDictionary(
          key_value_pair.second.Get<KeyValueStore>(), &dict);
      out_dict->emplace(key_value_pair.first, dict);
    } else {
      out_dict->insert(key_value_pair);
    }
  }
}

// static.
void KeyValueStore::ConvertFromVariantDictionary(
    const brillo::VariantDictionary& in_dict, KeyValueStore* out_store) {
  for (const auto& key_value_pair : in_dict) {
    if (key_value_pair.second.IsTypeCompatible<brillo::VariantDictionary>()) {
      // Special handling for nested brillo::VariantDictionary (convert it to
      // nested KeyValueStore).
      KeyValueStore store;
      ConvertFromVariantDictionary(
          key_value_pair.second.Get<brillo::VariantDictionary>(), &store);
      out_store->properties_.emplace(key_value_pair.first, store);
    } else {
      out_store->properties_.insert(key_value_pair);
    }
  }
}

// static.
void KeyValueStore::ConvertPathsToRpcIdentifiers(
  const vector<dbus::ObjectPath>& paths, vector<string>* rpc_identifiers) {
  for (const auto& path : paths) {
    rpc_identifiers->push_back(path.value());
  }
}

}  // namespace shill
