// Copyright (c) 2011 The Chromium OS 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 "shill/service_dbus_adaptor.h"

#include <map>
#include <string>

#include "shill/service.h"

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

namespace shill {

// static
const char ServiceDBusAdaptor::kInterfaceName[] = SHILL_INTERFACE;
// static
const char ServiceDBusAdaptor::kPath[] = "/service/";

ServiceDBusAdaptor::ServiceDBusAdaptor(DBus::Connection* conn,
                                       ServiceRefPtr service)
    : DBusAdaptor(conn, kPath + service->UniqueName()),
      service_(service) {}
ServiceDBusAdaptor::~ServiceDBusAdaptor() {}

void ServiceDBusAdaptor::UpdateConnected() {}

void ServiceDBusAdaptor::EmitBoolChanged(const std::string& name, bool value) {
  PropertyChanged(name, DBusAdaptor::BoolToVariant(value));
}

void ServiceDBusAdaptor::EmitUintChanged(const std::string& name,
                                         uint32 value) {
  PropertyChanged(name, DBusAdaptor::UInt32ToVariant(value));
}

void ServiceDBusAdaptor::EmitIntChanged(const std::string& name, int value) {
  PropertyChanged(name, DBusAdaptor::IntToVariant(value));
}

void ServiceDBusAdaptor::EmitStringChanged(const std::string& name,
                                           const std::string& value) {
  PropertyChanged(name, DBusAdaptor::StringToVariant(value));

}

map<string, ::DBus::Variant> ServiceDBusAdaptor::GetProperties(
    ::DBus::Error &error) {
  return map<string, ::DBus::Variant>();
}

void ServiceDBusAdaptor::SetProperty(const string& ,
                                     const ::DBus::Variant& ,
                                     ::DBus::Error &error) {
}

void ServiceDBusAdaptor::ClearProperty(const string& , ::DBus::Error &error) {
}

void ServiceDBusAdaptor::Connect(::DBus::Error &error) {
}

void ServiceDBusAdaptor::Disconnect(::DBus::Error &error) {
}

void ServiceDBusAdaptor::Remove(::DBus::Error &error) {
}

void ServiceDBusAdaptor::MoveBefore(const ::DBus::Path& ,
                                    ::DBus::Error &error) {
}

void ServiceDBusAdaptor::MoveAfter(const ::DBus::Path& ,
                                   ::DBus::Error &error) {
}

void ServiceDBusAdaptor::ActivateCellularModem(const string& ,
                                               ::DBus::Error &error) {
}

}  // namespace shill
