// Copyright (c) 2013 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/dbus/shill_device_client_stub.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_property_changed_observer.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "dbus/values_util.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

void ErrorFunction(const std::string& error_name,
                   const std::string& error_message) {
  LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
}

}  // namespace

ShillDeviceClientStub::ShillDeviceClientStub() : weak_ptr_factory_(this) {
}

ShillDeviceClientStub::~ShillDeviceClientStub() {
  STLDeleteContainerPairSecondPointers(
      observer_list_.begin(), observer_list_.end());
}

// ShillDeviceClient overrides.

void ShillDeviceClientStub::Init(dbus::Bus* bus) {}

void ShillDeviceClientStub::AddPropertyChangedObserver(
    const dbus::ObjectPath& device_path,
    ShillPropertyChangedObserver* observer){
  GetObserverList(device_path).AddObserver(observer);
}

void ShillDeviceClientStub::RemovePropertyChangedObserver(
    const dbus::ObjectPath& device_path,
    ShillPropertyChangedObserver* observer){
  GetObserverList(device_path).RemoveObserver(observer);
}

void ShillDeviceClientStub::GetProperties(
    const dbus::ObjectPath& device_path,
    const DictionaryValueCallback& callback){
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&ShillDeviceClientStub::PassStubDeviceProperties,
                 weak_ptr_factory_.GetWeakPtr(),
                 device_path, callback));
}

void ShillDeviceClientStub::ProposeScan(const dbus::ObjectPath& device_path,
                                        const VoidDBusMethodCallback& callback){
  PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
}

void ShillDeviceClientStub::SetProperty(const dbus::ObjectPath& device_path,
                                        const std::string& name,
                                        const base::Value& value,
                                        const base::Closure& callback,
                                        const ErrorCallback& error_callback){
  base::DictionaryValue* device_properties = NULL;
  if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
                                                       &device_properties)) {
    std::string error_name("org.chromium.flimflam.Error.Failure");
    std::string error_message("Failed");
    base::MessageLoop::current()->PostTask(FROM_HERE,
                                           base::Bind(error_callback,
                                                      error_name,
                                                      error_message));
    return;
  }
  device_properties->SetWithoutPathExpansion(name, value.DeepCopy());
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&ShillDeviceClientStub::NotifyObserversPropertyChanged,
                 weak_ptr_factory_.GetWeakPtr(), device_path, name));
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::ClearProperty(
    const dbus::ObjectPath& device_path,
    const std::string& name,
    const VoidDBusMethodCallback& callback){
  base::DictionaryValue* device_properties = NULL;
  if (!stub_devices_.GetDictionaryWithoutPathExpansion(device_path.value(),
                                                       &device_properties)) {
    PostVoidCallback(callback, DBUS_METHOD_CALL_FAILURE);
    return;
  }
  device_properties->RemoveWithoutPathExpansion(name, NULL);
  PostVoidCallback(callback, DBUS_METHOD_CALL_SUCCESS);
}

void ShillDeviceClientStub::AddIPConfig(
    const dbus::ObjectPath& device_path,
    const std::string& method,
    const ObjectPathDBusMethodCallback& callback){
  base::MessageLoop::current()->PostTask(FROM_HERE,
                                         base::Bind(callback,
                                                    DBUS_METHOD_CALL_SUCCESS,
                                                    dbus::ObjectPath()));
}

void ShillDeviceClientStub::RequirePin(const dbus::ObjectPath& device_path,
                                       const std::string& pin,
                                       bool require,
                                       const base::Closure& callback,
                                       const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::EnterPin(const dbus::ObjectPath& device_path,
                                     const std::string& pin,
                                     const base::Closure& callback,
                                     const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::UnblockPin(const dbus::ObjectPath& device_path,
                                       const std::string& puk,
                                       const std::string& pin,
                                       const base::Closure& callback,
                                       const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::ChangePin(const dbus::ObjectPath& device_path,
                                      const std::string& old_pin,
                                      const std::string& new_pin,
                                      const base::Closure& callback,
                                      const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::Register(const dbus::ObjectPath& device_path,
                                     const std::string& network_id,
                                     const base::Closure& callback,
                                     const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::SetCarrier(const dbus::ObjectPath& device_path,
                                       const std::string& carrier,
                                       const base::Closure& callback,
                                       const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

void ShillDeviceClientStub::Reset(const dbus::ObjectPath& device_path,
                                  const base::Closure& callback,
                                  const ErrorCallback& error_callback){
  base::MessageLoop::current()->PostTask(FROM_HERE, callback);
}

ShillDeviceClient::TestInterface* ShillDeviceClientStub::GetTestInterface(){
  return this;
}

// ShillDeviceClient::TestInterface overrides.

void ShillDeviceClientStub::AddDevice(const std::string& device_path,
                                      const std::string& type,
                                      const std::string& object_path){
  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
      AddDevice(device_path);

  base::DictionaryValue* properties = GetDeviceProperties(device_path);
  properties->SetWithoutPathExpansion(
      shill::kTypeProperty,
      base::Value::CreateStringValue(type));
  properties->SetWithoutPathExpansion(
      shill::kDBusObjectProperty,
      base::Value::CreateStringValue(object_path));
  properties->SetWithoutPathExpansion(
      shill::kDBusConnectionProperty,
      base::Value::CreateStringValue("/stub"));
}

void ShillDeviceClientStub::RemoveDevice(const std::string& device_path){
  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
      RemoveDevice(device_path);

  stub_devices_.RemoveWithoutPathExpansion(device_path, NULL);
}

void ShillDeviceClientStub::ClearDevices(){
  DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()->
      ClearDevices();

  stub_devices_.Clear();
}

void ShillDeviceClientStub::SetDeviceProperty(const std::string& device_path,
                                              const std::string& name,
                                              const base::Value& value){
  VLOG(1) << "SetDeviceProperty: " << device_path
          << ": " << name << " = " << value;
  SetProperty(dbus::ObjectPath(device_path), name, value,
              base::Bind(&base::DoNothing),
              base::Bind(&ErrorFunction));
}

std::string ShillDeviceClientStub::GetDevicePathForType(
    const std::string& type) {
  for (base::DictionaryValue::Iterator iter(stub_devices_);
       !iter.IsAtEnd(); iter.Advance()) {
    const base::DictionaryValue* properties = NULL;
    if (!iter.value().GetAsDictionary(&properties))
      continue;
    std::string prop_type;
    if (!properties->GetStringWithoutPathExpansion(
            shill::kTypeProperty, &prop_type) ||
        prop_type != type)
      continue;
    return iter.key();
  }
  return std::string();
}

void ShillDeviceClientStub::PassStubDeviceProperties(
    const dbus::ObjectPath& device_path,
    const DictionaryValueCallback& callback) const {
  const base::DictionaryValue* device_properties = NULL;
  if (!stub_devices_.GetDictionaryWithoutPathExpansion(
      device_path.value(), &device_properties)) {
    base::DictionaryValue empty_dictionary;
    callback.Run(DBUS_METHOD_CALL_FAILURE, empty_dictionary);
    return;
  }
  callback.Run(DBUS_METHOD_CALL_SUCCESS, *device_properties);
}

// Posts a task to run a void callback with status code |status|.
void ShillDeviceClientStub::PostVoidCallback(
    const VoidDBusMethodCallback& callback,
    DBusMethodCallStatus status) {
  base::MessageLoop::current()->PostTask(FROM_HERE,
                                   base::Bind(callback, status));
}

void ShillDeviceClientStub::NotifyObserversPropertyChanged(
    const dbus::ObjectPath& device_path,
    const std::string& property) {
  base::DictionaryValue* dict = NULL;
  std::string path = device_path.value();
  if (!stub_devices_.GetDictionaryWithoutPathExpansion(path, &dict)) {
    LOG(ERROR) << "Notify for unknown service: " << path;
    return;
  }
  base::Value* value = NULL;
  if (!dict->GetWithoutPathExpansion(property, &value)) {
    LOG(ERROR) << "Notify for unknown property: "
        << path << " : " << property;
    return;
  }
  FOR_EACH_OBSERVER(ShillPropertyChangedObserver,
                    GetObserverList(device_path),
                    OnPropertyChanged(property, *value));
}

base::DictionaryValue* ShillDeviceClientStub::GetDeviceProperties(
    const std::string& device_path) {
  base::DictionaryValue* properties = NULL;
  if (!stub_devices_.GetDictionaryWithoutPathExpansion(
      device_path, &properties)) {
    properties = new base::DictionaryValue;
    stub_devices_.SetWithoutPathExpansion(device_path, properties);
  }
  return properties;
}

ShillDeviceClientStub::PropertyObserverList&
ShillDeviceClientStub::GetObserverList(const dbus::ObjectPath& device_path) {
  std::map<dbus::ObjectPath, PropertyObserverList*>::iterator iter =
      observer_list_.find(device_path);
  if (iter != observer_list_.end())
    return *(iter->second);
  PropertyObserverList* observer_list = new PropertyObserverList();
  observer_list_[device_path] = observer_list;
  return *observer_list;
}

}  // namespace chromeos
