// 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 <memory>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>
#include <dbus/property.h>
#include <shill/dbus-proxies.h>

namespace debugd {

namespace {

const int kFlimflamLogLevelVerbose3 = -3;
const int kFlimflamLogLevelInfo = 0;

const char kSupplicantServiceName[] = "fi.w1.wpa_supplicant1";
const char kSupplicantObjectPath[] = "/fi/w1/wpa_supplicant1";
const char kSupplicantDebugLevel[] = "DebugLevel";

class SupplicantProxy {
 public:
  struct Properties : public dbus::PropertySet {
    dbus::Property<std::string> debug_level;

    explicit Properties(dbus::ObjectProxy* proxy)
        : dbus::PropertySet(proxy,
                            kSupplicantServiceName,
                            dbus::PropertySet::PropertyChangedCallback()) {
      RegisterProperty(kSupplicantDebugLevel, &debug_level);
    }

    ~Properties() override = default;
  };

  explicit SupplicantProxy(scoped_refptr<dbus::Bus> bus)
      : bus_(bus),
        properties_(bus->GetObjectProxy(
            kSupplicantServiceName, dbus::ObjectPath(kSupplicantObjectPath))) {}
  SupplicantProxy(const SupplicantProxy&) = delete;
  SupplicantProxy& operator=(const SupplicantProxy&) = delete;

  ~SupplicantProxy() {}

  void SetDebugLevel(const std::string& level) {
    properties_.debug_level.SetAndBlock(level);
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  Properties properties_;
};

// Marvell wifi.
constexpr char kMwifiexDebugFlag[] =
    "/sys/kernel/debug/mwifiex/mlan0/debug_mask";
// Enable extra debugging: MSG | FATAL | ERROR | CMD | EVENT.
constexpr char kMwifiexEnable[] = "0x37";
// Default debugging level: MSG | FATAL | ERROR.
constexpr char kMwifiexDisable[] = "0x7";

// Intel wifi.
constexpr char kIwlwifiDebugFlag[] = "/sys/module/iwlwifi/parameters/debug";
// Full debugging: see below file for details on each bit:
// drivers/net/wireless-$(WIFIVERSION)/iwl7000/iwlwifi/iwl-debug.h
constexpr char kIwlwifiEnable[] = "0xFFFFFFFF";
// Default debugging: none
constexpr char kIwlwifiDisable[] = "0x0";

// Qualcomm/Atheros wifi.
constexpr char kAth10kDebugFlag[] =
    "/sys/module/ath10k_core/parameters/debug_mask";
// Full debugging: see below file for details on each bit:
// drivers/net/wireless/ath/ath10k/debug.h
constexpr char kAth10kEnable[] = "0xFFFFFFFF";
// Default debugging: none
constexpr char kAth10kDisable[] = "0x0";

// Realtek wifi.
constexpr char kRtw88DebugFlag[] =
    "/sys/module/rtw88_core/parameters/debug_mask";
// Full debugging: see below file for details on each bit:
// drivers/net/wireless/realtek/rtw88/debug.h
constexpr char kRtw88Enable[] = "0xFFFFFFFF";
// Default debugging: none
constexpr char kRtw88Disable[] = "0x0";

void MaybeWriteSysfs(const char* sysfs_path, const char* data) {
  base::FilePath path(sysfs_path);

  if (base::PathExists(path)) {
    int len = strlen(data);
    if (base::WriteFile(path, data, len) != len)
      PLOG(WARNING) << "Writing to " << path.value() << " failed";
  }
}
void WifiSetDebugLevels(bool enable) {
  MaybeWriteSysfs(kIwlwifiDebugFlag, enable ? kIwlwifiEnable : kIwlwifiDisable);

  MaybeWriteSysfs(kMwifiexDebugFlag, enable ? kMwifiexEnable : kMwifiexDisable);

  MaybeWriteSysfs(kAth10kDebugFlag, enable ? kAth10kEnable : kAth10kDisable);

  MaybeWriteSysfs(kRtw88DebugFlag, enable ? kRtw88Enable : kRtw88Disable);
}

}  // namespace

DebugModeTool::DebugModeTool(scoped_refptr<dbus::Bus> bus) : bus_(bus) {}

void DebugModeTool::SetDebugMode(const std::string& subsystem) {
  std::string flimflam_tags;
  std::string supplicant_level = "info";
  std::string modemmanager_level = "info";
  bool wifi_debug = false;

  if (subsystem == "wifi") {
    flimflam_tags = "service+wifi+inet+device+manager";
    supplicant_level = "msgdump";
    wifi_debug = true;
  } else if (subsystem == "cellular") {
    flimflam_tags = "service+cellular+modem+device+manager";
    modemmanager_level = "debug";
  } else if (subsystem == "ethernet") {
    flimflam_tags = "service+ethernet+device+manager";
  } else if (subsystem == "none") {
    flimflam_tags = "";
  }

  auto shill = std::make_unique<org::chromium::flimflam::ManagerProxy>(bus_);
  if (shill) {
    shill->SetDebugTags(flimflam_tags, nullptr);
    if (flimflam_tags.length()) {
      shill->SetDebugLevel(kFlimflamLogLevelVerbose3, nullptr);
    } else {
      shill->SetDebugLevel(kFlimflamLogLevelInfo, nullptr);
    }
  }

  WifiSetDebugLevels(wifi_debug);

  SupplicantProxy supplicant(bus_);
  supplicant.SetDebugLevel(supplicant_level);

  SetModemManagerLogging(modemmanager_level);
}

void DebugModeTool::SetModemManagerLogging(const std::string& level) {
#if USE_CELLULAR
  static constexpr char kSetLogging[] = "SetLogging";

  dbus::ObjectProxy* proxy = bus_->GetObjectProxy(
      modemmanager::kModemManager1ServiceName,
      dbus::ObjectPath(modemmanager::kModemManager1ServicePath));
  dbus::MethodCall method_call(modemmanager::kModemManager1ServiceName,
                               kSetLogging);
  dbus::MessageWriter writer(&method_call);
  writer.AppendString(level);
  proxy->CallMethodAndBlock(&method_call,
                            dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
#endif  // USE_CELLULAR
}

}  // namespace debugd
