// Copyright (c) 2012 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 "debug_mode_tool.h"

#include <base/file_util.h>
#include <chromeos/dbus/service_constants.h>

#include "shill/dbus_proxies/org.chromium.flimflam.Manager.h"
#include "dbus_proxies/org.freedesktop.DBus.Properties.h"

#if USE_CELLULAR
#include "dbus_proxies/org.freedesktop.ModemManager.h"
#include "dbus_proxies/org.freedesktop.ModemManager1.h"
#endif  // USE_CELLULAR

namespace debugd {

const char* const kFlimflamPath = "/";
const char* const kFlimflamService = "org.chromium.flimflam";

const char* const kSupplicantPath = "/fi/w1/wpa_supplicant1";
const char* const kSupplicantService = "fi.w1.wpa_supplicant1";
const char* const kSupplicantIface = "fi.w1.wpa_supplicant1";

class ManagerProxy : public org::chromium::flimflam::Manager_proxy,
                     public DBus::ObjectProxy {
 public:
  ManagerProxy(DBus::Connection* connection,
               const char* path,
               const char* service)
      : DBus::ObjectProxy(*connection, path, service) {}
  virtual ~ManagerProxy() {}
  virtual void PropertyChanged(const std::string&, const DBus::Variant&) {}
  virtual void StateChanged(const std::string&) {}
};

#if USE_CELLULAR

const char* const kDBusPath = "/org/freedesktop/DBus";
const char* const kDBusInterface = "org.freedesktop.DBus";
const char* const kDBusListNames = "ListNames";

const char* const kModemManager = "ModemManager";

class ModemManagerProxy : public org::freedesktop::ModemManager_proxy,
                          public DBus::ObjectProxy {
 public:
  ModemManagerProxy(DBus::Connection* connection,
                    const char* path,
                    const char* service)
      : DBus::ObjectProxy(*connection, path, service) {}
  virtual ~ModemManagerProxy() {}
  virtual void DeviceAdded(const DBus::Path&) {}
  virtual void DeviceRemoved(const DBus::Path&) {}
};

class ModemManager1Proxy : public org::freedesktop::ModemManager1_proxy,
                           public DBus::ObjectProxy {
 public:
  ModemManager1Proxy(DBus::Connection* connection,
                     const char* path,
                     const char* service)
      : DBus::ObjectProxy(*connection, path, service) {}
  virtual ~ModemManager1Proxy() {}
  virtual void DeviceAdded(const DBus::Path&) {}
  virtual void DeviceRemoved(const DBus::Path&) {}
};

#endif  // USE_CELLULAR

class PropertiesProxy : public org::freedesktop::DBus::Properties_proxy,
                        public DBus::ObjectProxy {
 public:
  PropertiesProxy(DBus::Connection* connection,
                  const char* path,
                  const char* service)
      : DBus::ObjectProxy(*connection, path, service) {}
  virtual ~PropertiesProxy() {}
};

DebugModeTool::DebugModeTool(DBus::Connection* connection)
    : connection_(connection) { }

DebugModeTool::~DebugModeTool() { }

void DebugModeTool::SetDebugMode(const std::string& subsystem,
                                 DBus::Error*) {
  ManagerProxy flimflam(connection_, kFlimflamPath, kFlimflamService);
  PropertiesProxy supplicant(connection_, kSupplicantPath, kSupplicantService);
  std::string flimflam_value;
  DBus::Variant supplicant_value;
  std::string modemmanager_value = "info";
  std::string supplicant_level = "info";
  if (subsystem == "wifi") {
    flimflam_value = "service+wifi+inet+device+manager";
    supplicant_level = "msgdump";
  } else if (subsystem == "wimax") {
    flimflam_value = "service+wimax+device+manager";
  } else if (subsystem == "cellular") {
    flimflam_value = "service+cellular+modem+device+manager";
  } else if (subsystem == "ethernet") {
    flimflam_value = "service+ethernet+device+manager";
  } else if (subsystem == "none") {
    flimflam_value = "";
  }
  flimflam.SetDebugTags(flimflam_value);
  supplicant_value.writer().append_string(supplicant_level.c_str());
  supplicant.Set(kSupplicantIface, "DebugLevel", supplicant_value);
  SetAllModemManagersLogging(modemmanager_value);
}

void DebugModeTool::GetAllModemManagers(std::vector<std::string>* managers) {
#if USE_CELLULAR
  managers->clear();

  DBus::CallMessage msg;
  DBus::MessageIter iter;
  msg.destination(kDBusInterface);
  msg.interface(kDBusInterface);
  msg.member(kDBusListNames);
  msg.path(kDBusPath);
  DBus::Message ret = connection_->send_blocking(msg, -1);
  iter = ret.reader();
  iter = iter.recurse();
  while (!iter.at_end()) {
    std::string name(iter.get_string());
    if (name.find(kModemManager) != std::string::npos)
      managers->push_back(name);
    ++iter;
  }
#endif  // USE_CELLULAR
}

void DebugModeTool::SetAllModemManagersLogging(const std::string& level) {
#if USE_CELLULAR
  std::vector<std::string> managers;
  GetAllModemManagers(&managers);
  for (size_t i = 0; i < managers.size(); ++i) {
    const std::string& manager = managers[i];
    if (manager == cromo::kCromoServiceName) {
      ModemManagerProxy modemmanager(connection_,
                                     cromo::kCromoServicePath,
                                     cromo::kCromoServiceName);
      modemmanager.SetLogging(level == "err" ? "error" : level);
    } else if (manager == modemmanager::kModemManager1ServiceName) {
      ModemManager1Proxy modemmanager(connection_,
                                      modemmanager::kModemManager1ServicePath,
                                      modemmanager::kModemManager1ServiceName);
      modemmanager.SetLogging(level);
    }
  }
#endif  // USE_CELLULAR
}

}  // namespace debugd
