// 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/dbus/shill/shill_device_client.h"

#include <map>
#include <utility>

#include "base/bind.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/values.h"
#include "chromeos/dbus/shill/fake_shill_device_client.h"
#include "chromeos/dbus/shill/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 "net/base/ip_endpoint.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

ShillDeviceClient* g_instance = nullptr;

// The ShillDeviceClient implementation.
class ShillDeviceClientImpl : public ShillDeviceClient {
 public:
  explicit ShillDeviceClientImpl(dbus::Bus* bus) : bus_(bus) {}

  ~ShillDeviceClientImpl() override {
    for (HelperMap::iterator iter = helpers_.begin(); iter != helpers_.end();
         ++iter) {
      // This *should* never happen, yet we're getting crash reports that
      // seem to imply that it does happen sometimes.  Adding CHECKs here
      // so we can determine more accurately where the problem lies.
      // See: http://crbug.com/170541
      CHECK(iter->second) << "null Helper found in helper list.";
      delete iter->second;
    }
    helpers_.clear();
  }

  ///////////////////////////////////////
  // ShillDeviceClient overrides.
  void AddPropertyChangedObserver(
      const dbus::ObjectPath& device_path,
      ShillPropertyChangedObserver* observer) override {
    GetHelper(device_path)->AddPropertyChangedObserver(observer);
  }

  void RemovePropertyChangedObserver(
      const dbus::ObjectPath& device_path,
      ShillPropertyChangedObserver* observer) override {
    GetHelper(device_path)->RemovePropertyChangedObserver(observer);
  }

  void GetProperties(const dbus::ObjectPath& device_path,
                     const DictionaryValueCallback& callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kGetPropertiesFunction);
    GetHelper(device_path)->CallDictionaryValueMethod(&method_call, callback);
  }

  void SetProperty(const dbus::ObjectPath& device_path,
                   const std::string& name,
                   const base::Value& value,
                   const base::Closure& callback,
                   const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kSetPropertyFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(name);
    ShillClientHelper::AppendValueDataAsVariant(&writer, value);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void ClearProperty(const dbus::ObjectPath& device_path,
                     const std::string& name,
                     VoidDBusMethodCallback callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kClearPropertyFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(name);
    GetHelper(device_path)->CallVoidMethod(&method_call, std::move(callback));
  }

  void RequirePin(const dbus::ObjectPath& device_path,
                  const std::string& pin,
                  bool require,
                  const base::Closure& callback,
                  const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kRequirePinFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(pin);
    writer.AppendBool(require);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void EnterPin(const dbus::ObjectPath& device_path,
                const std::string& pin,
                const base::Closure& callback,
                const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kEnterPinFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(pin);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void UnblockPin(const dbus::ObjectPath& device_path,
                  const std::string& puk,
                  const std::string& pin,
                  const base::Closure& callback,
                  const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kUnblockPinFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(puk);
    writer.AppendString(pin);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void ChangePin(const dbus::ObjectPath& device_path,
                 const std::string& old_pin,
                 const std::string& new_pin,
                 const base::Closure& callback,
                 const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kChangePinFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(old_pin);
    writer.AppendString(new_pin);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void Register(const dbus::ObjectPath& device_path,
                const std::string& network_id,
                const base::Closure& callback,
                const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kRegisterFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(network_id);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void Reset(const dbus::ObjectPath& device_path,
             const base::Closure& callback,
             const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kResetFunction);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void PerformTDLSOperation(const dbus::ObjectPath& device_path,
                            const std::string& operation,
                            const std::string& peer,
                            const StringCallback& callback,
                            const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kPerformTDLSOperationFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(operation);
    writer.AppendString(peer);
    GetHelper(device_path)
        ->CallStringMethodWithErrorCallback(&method_call, callback,
                                            error_callback);
  }

  void AddWakeOnPacketConnection(const dbus::ObjectPath& device_path,
                                 const net::IPEndPoint& ip_endpoint,
                                 const base::Closure& callback,
                                 const ErrorCallback& error_callback) override {
    if (ip_endpoint.address().empty()) {
      LOG(ERROR) << "AddWakeOnPacketConnection: null address";
      return;
    }
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kAddWakeOnPacketConnectionFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(ip_endpoint.ToStringWithoutPort());
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void AddWakeOnPacketOfTypes(const dbus::ObjectPath& device_path,
                              const std::vector<std::string>& types,
                              const base::Closure& callback,
                              const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kAddWakeOnPacketOfTypesFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendArrayOfStrings(types);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void RemoveWakeOnPacketConnection(
      const dbus::ObjectPath& device_path,
      const net::IPEndPoint& ip_endpoint,
      const base::Closure& callback,
      const ErrorCallback& error_callback) override {
    if (ip_endpoint.address().empty()) {
      LOG(ERROR) << "RemoveWakeOnPacketConnection: null address";
      return;
    }
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kRemoveWakeOnPacketConnectionFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(ip_endpoint.ToStringWithoutPort());
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void RemoveWakeOnPacketOfTypes(const dbus::ObjectPath& device_path,
                                 const std::vector<std::string>& types,
                                 const base::Closure& callback,
                                 const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(shill::kFlimflamDeviceInterface,
                                 shill::kRemoveWakeOnPacketOfTypesFunction);
    dbus::MessageWriter writer(&method_call);
    writer.AppendArrayOfStrings(types);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  void RemoveAllWakeOnPacketConnections(
      const dbus::ObjectPath& device_path,
      const base::Closure& callback,
      const ErrorCallback& error_callback) override {
    dbus::MethodCall method_call(
        shill::kFlimflamDeviceInterface,
        shill::kRemoveAllWakeOnPacketConnectionsFunction);
    GetHelper(device_path)
        ->CallVoidMethodWithErrorCallback(&method_call, callback,
                                          error_callback);
  }

  TestInterface* GetTestInterface() override { return nullptr; }

 private:
  typedef std::map<std::string, ShillClientHelper*> HelperMap;

  // Returns the corresponding ShillClientHelper for the profile.
  ShillClientHelper* GetHelper(const dbus::ObjectPath& device_path) {
    HelperMap::iterator it = helpers_.find(device_path.value());
    if (it != helpers_.end()) {
      CHECK(it->second) << "Found a null helper in the list.";
      return it->second;
    }

    // There is no helper for the profile, create it.
    dbus::ObjectProxy* object_proxy =
        bus_->GetObjectProxy(shill::kFlimflamServiceName, device_path);
    ShillClientHelper* helper = new ShillClientHelper(object_proxy);
    CHECK(helper) << "Unable to create Shill client helper.";
    helper->MonitorPropertyChanged(shill::kFlimflamDeviceInterface);
    helpers_.insert(HelperMap::value_type(device_path.value(), helper));
    return helper;
  }

  dbus::Bus* bus_;
  HelperMap helpers_;

  DISALLOW_COPY_AND_ASSIGN(ShillDeviceClientImpl);
};

}  // namespace

ShillDeviceClient::ShillDeviceClient() {
  DCHECK(!g_instance);
  g_instance = this;
}

ShillDeviceClient::~ShillDeviceClient() {
  DCHECK_EQ(this, g_instance);
  g_instance = nullptr;
}

// static
void ShillDeviceClient::Initialize(dbus::Bus* bus) {
  DCHECK(bus);
  new ShillDeviceClientImpl(bus);
}

// static
void ShillDeviceClient::InitializeFake() {
  new FakeShillDeviceClient();
}

// static
void ShillDeviceClient::Shutdown() {
  DCHECK(g_instance);
  delete g_instance;
}

// static
ShillDeviceClient* ShillDeviceClient::Get() {
  return g_instance;
}

}  // namespace chromeos
