// Copyright 2019 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/cros_healthd_tool.h"

#include <map>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/process/launch.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_util.h>

#include "debugd/src/error_utils.h"
#include "debugd/src/process_with_output.h"

namespace debugd {

namespace {

constexpr char kErrorPath[] = "org.chromium.debugd.CrosHealthdToolError";
constexpr char kSandboxDirPath[] = "/usr/share/policy/";
constexpr char kRunAs[] = "healthd_ec";
// The ectool i2cread command below follows the format:
// ectool i2cread [NUM_BITS] [PORT] [BATTERY_I2C_ADDRESS (addr8)] [OFFSET]
// Note that [NUM_BITS] can either be 8 or 16.
constexpr char kEctoolBinary[] = "/usr/sbin/ectool";
constexpr char kI2cReadCommand[] = "i2cread";
// The specification for smart battery can be found at:
// http://sbs-forum.org/specs/sbdat110.pdf. This states
// that both the temperature and manufacture_date commands
// use the "Read Word" SMBus Protocol, which is 16 bits.
constexpr char kNumBits[] = "16";
// The i2c address is well defined at:
// src/platform/ec/include/battery_smart.h
constexpr char kBatteryI2cAddress[] = "0x16";
// The only i2cread argument different across models is the port.
const std::map<std::string, std::string> kModelToPort = {
  {"sona", "2"},
  {"careena", "0"},
  {"dratini", "5"},
  {"dorp", "0"}};
const std::map<std::string, std::string> kMetricNameToOffset = {
  {"temperature_smart", "0x08"},
  {"manufacture_date_smart", "0x1b"}};
// The ectool command used to collect fan speed in RPM.
constexpr char kGetFanRpmCommand[] = "pwmgetfanrpm";

// Returns the ectool policy file corresponding to the provided
// |ectool_command|.
std::string GetEctoolPolicyFile(const std::string& ectool_command) {
  return base::StringPrintf("ectool_%s-seccomp.policy", ectool_command.c_str());
}

// Runs ectool with the provided |ectool_args| in a sandboxed process. Returns
// true on success.
bool RunEctoolWithArgs(brillo::ErrorPtr* error,
                       const base::FilePath& seccomp_policy_path,
                       const std::vector<std::string> ectool_args,
                       std::string* output) {
  if (!base::PathExists(seccomp_policy_path)) {
    DEBUGD_ADD_ERROR(error, kErrorPath,
                     "Sandbox info is missing for this architecture.");
    return false;
  }

  // Minijail setup for ectool.
  std::vector<std::string> parsed_args;
  parsed_args.push_back("-c");
  parsed_args.push_back("cap_sys_rawio=e");
  parsed_args.push_back("-b");
  parsed_args.push_back("/dev/cros_ec");

  ProcessWithOutput process;
  process.SandboxAs(kRunAs, kRunAs);
  process.SetSeccompFilterPolicyFile(seccomp_policy_path.MaybeAsASCII());
  process.InheritUsergroups();
  if (!process.Init(parsed_args)) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Process initialization failure.");
    return false;
  }

  process.AddArg(kEctoolBinary);
  for (const auto& arg : ectool_args)
    process.AddArg(arg);
  if (process.Run() != EXIT_SUCCESS) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Failed to run process.");
    return false;
  }

  if (!process.GetOutput(output)) {
    DEBUGD_ADD_ERROR(error, kErrorPath, "Failed to get output from process.");
    return false;
  }

  return true;
}

}  // namespace

bool CrosHealthdTool::CollectFanSpeed(brillo::ErrorPtr* error,
                                      std::string* output) {
  const auto seccomp_policy_path =
      base::FilePath(kSandboxDirPath)
          .Append(GetEctoolPolicyFile(kGetFanRpmCommand));
  std::vector<std::string> ectool_args = {kGetFanRpmCommand};
  if (!RunEctoolWithArgs(error, seccomp_policy_path, ectool_args, output))
    return false;

  return true;
}

// Note that this is a short-term solution to retrieving battery metrics.
// A long term solution is being discussed at: crbug.com/1047277.
bool CrosHealthdTool::CollectSmartBatteryMetric(brillo::ErrorPtr* error,
                                                const std::string& metric_name,
                                                std::string* output) {
  std::string model_name;
  if (!base::GetAppOutputAndError({"cros_config", "/", "name"}, &model_name)) {
    DEBUGD_ADD_ERROR(error, kErrorPath,
                     base::StringPrintf("Failed to run cros_config: %s",
                                        model_name.c_str()));
    return false;
  }

  auto it = kModelToPort.find(model_name);
  if (it == kModelToPort.end()) {
    DEBUGD_ADD_ERROR(
        error, kErrorPath,
        base::StringPrintf("Failed to find port for model: %s and metric: %s",
                           model_name.c_str(), metric_name.c_str()));
    return false;
  }

  const std::string port_number = it->second;
  auto metric_name_it = kMetricNameToOffset.find(metric_name);
  if (metric_name_it == kMetricNameToOffset.end()) {
    DEBUGD_ADD_ERROR(
        error, kErrorPath,
        base::StringPrintf("Failed to find offset for model: %s and metric: %s",
                           model_name.c_str(), metric_name.c_str()));
    return false;
  }

  const std::string offset = metric_name_it->second;
  std::vector<std::string> ectool_args = {
      kI2cReadCommand, kNumBits, port_number, kBatteryI2cAddress, offset};
  const auto seccomp_policy_path =
      base::FilePath(kSandboxDirPath)
          .Append(GetEctoolPolicyFile(kI2cReadCommand));
  if (!RunEctoolWithArgs(error, seccomp_policy_path, ectool_args, output))
    return false;

  return true;
}

}  // namespace debugd
