// Copyright (c) 2012 The Chromium 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 "chromeos/network/managed_state.h"

#include <stdint.h>

#include <memory>

#include "base/logging.h"
#include "base/values.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_type_pattern.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

bool ManagedState::Matches(const NetworkTypePattern& pattern) const {
  return pattern.MatchesType(type());
}

// static
std::string ManagedState::TypeToString(ManagedType type) {
  switch (type) {
    case MANAGED_TYPE_NETWORK:
      return "Network";
    case MANAGED_TYPE_DEVICE:
      return "Device";
  }
  return "Unknown";
}

ManagedState::ManagedState(ManagedType type, const std::string& path)
    : managed_type_(type),
      path_(path),
      update_received_(false),
      update_requested_(false) {
}

ManagedState::~ManagedState() = default;

std::unique_ptr<ManagedState> ManagedState::Create(ManagedType type,
                                                   const std::string& path) {
  switch (type) {
    case MANAGED_TYPE_NETWORK:
      return std::make_unique<NetworkState>(path);
    case MANAGED_TYPE_DEVICE:
      return std::make_unique<DeviceState>(path);
  }
  return NULL;
}

NetworkState* ManagedState::AsNetworkState() {
  if (managed_type() == MANAGED_TYPE_NETWORK)
    return static_cast<NetworkState*>(this);
  return NULL;
}

DeviceState* ManagedState::AsDeviceState() {
  if (managed_type() == MANAGED_TYPE_DEVICE)
    return static_cast<DeviceState*>(this);
  return NULL;
}

bool ManagedState::InitialPropertiesReceived(
    const base::DictionaryValue& properties) {
  return false;
}

void ManagedState::GetStateProperties(base::DictionaryValue* dictionary) const {
  dictionary->SetKey(shill::kNameProperty, base::Value(name()));
  dictionary->SetKey(shill::kTypeProperty, base::Value(type()));
}

bool ManagedState::ManagedStatePropertyChanged(const std::string& key,
                                               const base::Value& value) {
  if (key == shill::kNameProperty) {
    return GetStringValue(key, value, &name_);
  } else if (key == shill::kTypeProperty) {
    return GetStringValue(key, value, &type_);
  }
  return false;
}

bool ManagedState::GetBooleanValue(const std::string& key,
                                   const base::Value& value,
                                   bool* out_value) {
  bool new_value;
  if (!value.GetAsBoolean(&new_value)) {
    NET_LOG_ERROR("Error parsing state value", path() + "." + key);
    return false;
  }
  if (*out_value == new_value)
    return false;
  *out_value = new_value;
  return true;
}

bool ManagedState::GetIntegerValue(const std::string& key,
                                   const base::Value& value,
                                   int* out_value) {
  int new_value;
  if (!value.GetAsInteger(&new_value)) {
    NET_LOG_ERROR("Error parsing state value", path() + "." + key);
    return false;
  }
  if (*out_value == new_value)
    return false;
  *out_value = new_value;
  return true;
}

bool ManagedState::GetStringValue(const std::string& key,
                                  const base::Value& value,
                                  std::string* out_value) {
  std::string new_value;
  if (!value.GetAsString(&new_value)) {
    NET_LOG_ERROR("Error parsing state: " + key, path());
    return false;
  }
  if (*out_value == new_value)
    return false;
  *out_value = new_value;
  return true;
}

bool ManagedState::GetUInt32Value(const std::string& key,
                                  const base::Value& value,
                                  uint32_t* out_value) {
  // base::Value restricts the number types to BOOL, INTEGER, and DOUBLE only.
  // uint32_t will automatically get converted to a double, which is why we try
  // to obtain the value as a double (see dbus/values_util.h).
  uint32_t new_value;
  double double_value;
  if (!value.GetAsDouble(&double_value) || double_value < 0) {
    NET_LOG_ERROR("Error parsing state value", path() + "." + key);
    return false;
  }
  new_value = static_cast<uint32_t>(double_value);
  if (*out_value == new_value)
    return false;
  *out_value = new_value;
  return true;
}

}  // namespace chromeos
