// Copyright 2015 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 "thermald/ath10k_interface.h"

#include <map>
#include <string>
#include <utility>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"

#include "thermald/cooling_device.h"

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

namespace thermald {

Ath10kInterface::Ath10kInterface(const string &name)
    : NetworkInterface(name),
      tx_duty_cycle_(-1) {
  if (!IsAth10kInterface(name)) {
    LOG(WARNING) << "[" << name << "] '" << name
                 << "' is not an ath10k interface";
  }

  if (HasThermalSupport(name)) {
    DetermineCoolingDevice();
  }
}

bool Ath10kInterface::SetMaxTxDutyCycle(unsigned int value) {
  if (value > 100) {
    LOG(WARNING) << "[" << name()
                 << "] Invalid value for maximum tx duty cycle: " << value;
    return false;
  }

  if (!HasThermalSupport()) {
    LOG(WARNING) << "[" << name() << "] Unable to set maximum tx duty cycle: "
                 << "Interface has no thermal support";
    return false;
  }

  if (value == tx_duty_cycle_) {
    DLOG(INFO) << "[" << name() << "] Skipped setting of maximum tx duty cycle"
               << ", value unchanged (" << value << ")";
    return true;
  }

  DLOG(INFO) << "[" << name() << "] Set maximum tx duty cycle to " << value;

  return cooling_device_->SetThrottleState(100 - value);
}

void Ath10kInterface::DetermineCoolingDevice() {
  string symlink(base::StringPrintf(
      "/sys/class/net/%s/phy80211/device/cooling_device", name().c_str()));
  base::FilePath target;
  if (!base::ReadSymbolicLink(base::FilePath(symlink), &target)) {
    LOG(ERROR) << "[" << name() << "] Unable to determine cooling device. "
               << "Failed to read symbolic link " << symlink;
    return;
  }

  // The target of the symlink is /sys/class/thermal/cooling_deviceX. Extract
  // the id of the cooling device from it.
  string cooling_dev_path(target.value());
  size_t pos = cooling_dev_path.find_last_not_of("0123456789");
  if ((pos == string::npos) ||
      (pos == cooling_dev_path.length() -1)) {
    LOG(ERROR) << "[" << name() << "] Unable to determine cooling device from "
               << "symlink: " << symlink;
    return;
  }

  int id;
  base::StringToInt(cooling_dev_path.substr(pos + 1), &id);
  cooling_device_.reset(new CoolingDevice(id));
}

bool Ath10kInterface::HasThermalSupport() const {
  return cooling_device_.get() != nullptr;
}

bool Ath10kInterface::IsAth10kInterface(const std::string &name) {
  base::FilePath target;
  if (!base::ReadSymbolicLink(
          base::FilePath(base::StringPrintf(
              "/sys/class/net/%s/phy80211/device/driver/module", name.c_str())),
                         &target)) {
    if (!Exists(name)) {
      DLOG(INFO) << "Network device '" << name << "' does not exist";
      return false;
    } else {
      DLOG(INFO) << "Network device '" << name
                 << "' is not a wireless interface";
      return false;
    }
  }

  base::FilePath driver(target.BaseName());
  return driver.value() == "ath10k_pci" || driver.value() == "ath10k_snoc";
}

bool Ath10kInterface::HasThermalSupport(const std::string &name) {
  string phydev_path(base::StringPrintf("/sys/class/net/%s/phy80211/device",
                                        name.c_str()));
  if (base::DirectoryExists(base::FilePath(phydev_path + "/hwmon")) &&
      base::DirectoryExists(base::FilePath(phydev_path + "/cooling_device"))) {
    return true;
  } else {
    if (!IsAth10kInterface(name)) {
      DLOG(INFO) << "'" << name << "' is not an ath10k interface";
    }
    return false;
  }
}

}  // namespace thermald
