// 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 "debugd/src/debug_mode_tool.h"

#include <base/files/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 int kFlimflamLogLevelVerbose3 = -3;
const int kFlimflamLogLevelInfo = 0;

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) {}
  ~ManagerProxy() override = default;
  void PropertyChanged(const std::string&, const DBus::Variant&) override {}
  void StateChanged(const std::string&) override {}
};

#if USE_CELLULAR

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) {}
  ~ModemManagerProxy() override = default;
  void DeviceAdded(const DBus::Path&) override {}
  void DeviceRemoved(const DBus::Path&) override {}
};

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) {}
  ~ModemManager1Proxy() override = default;
};

#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) {}
  ~PropertiesProxy() override = default;
};

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

void DebugModeTool::SetDebugMode(const std::string& subsystem,
                                 DBus::Error*) {
  ManagerProxy flimflam(connection_,
                        shill::kFlimflamServicePath,
                        shill::kFlimflamServiceName);
  PropertiesProxy supplicant(connection_, kSupplicantPath, kSupplicantService);
  std::string flimflam_tags;
  DBus::Variant supplicant_value;
  std::string modemmanager_value = "info";
  std::string supplicant_level = "info";
  if (subsystem == "wifi") {
    flimflam_tags = "service+wifi+inet+device+manager";
    supplicant_level = "msgdump";
  } else if (subsystem == "wimax") {
    flimflam_tags = "service+wimax+device+manager";
  } else if (subsystem == "cellular") {
    flimflam_tags = "service+cellular+modem+device+manager";
  } else if (subsystem == "ethernet") {
    flimflam_tags = "service+ethernet+device+manager";
  } else if (subsystem == "none") {
    flimflam_tags = "";
  }
  flimflam.SetDebugTags(flimflam_tags);
  if (flimflam_tags.length()) {
    flimflam.SetDebugLevel(kFlimflamLogLevelVerbose3);
  } else {
    flimflam.SetDebugLevel(kFlimflamLogLevelInfo);
  }
  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(dbus::kDBusInterface);
  msg.interface(dbus::kDBusInterface);
  msg.member(kDBusListNames);
  msg.path(dbus::kDBusServicePath);
  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
