// 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 <iomanip>
#include <iostream>  // NOLINT(readability/streams)
#include <string>

#include <base/at_exit.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/flag_helper.h>

#include "power_manager/common/power_constants.h"
#include "power_manager/common/prefs.h"
#include "power_manager/powerd/system/dbus_wrapper_stub.h"
#include "power_manager/powerd/system/power_supply.h"
#include "power_manager/powerd/system/udev_stub.h"

// Displays info about battery and line power.

using base::TimeDelta;
using power_manager::system::PowerStatus;

namespace {

// Number of columns that should be used to display field names.
const int kFieldNameColumns = 27;

std::string BoolToString(bool value) {
  return value ? "yes" : "no";
}

template <class T>
std::string ValueToString(T value) {
  std::stringstream stream;
  stream << value;
  return stream.str();
}

class InfoDisplay {
 public:
  InfoDisplay() : name_indent_(0), value_indent_(0) {}

  void SetIndent(int name_indent, int value_indent) {
    name_indent_ = name_indent;
    value_indent_ = value_indent;
  }

  void PrintStringValue(const std::string& name_field,
                        const std::string& value_field) {
    std::cout << std::setw(name_indent_) << ""
              << std::setw(value_indent_ - name_indent_)
              << std::setiosflags(std::ios::left)
              << std::resetiosflags(std::ios::right) << name_field + ":"
              << value_field << std::endl;
  }

  template <class T>
  void PrintValue(const std::string& name_field, T value) {
    PrintStringValue(name_field, ValueToString(value));
  }

  void PrintString(const std::string& string) {
    std::cout << std::setw(name_indent_) << "" << string << std::endl;
  }

 private:
  int name_indent_;
  int value_indent_;

  DISALLOW_COPY_AND_ASSIGN(InfoDisplay);
};

}  // namespace

int main(int argc, char** argv) {
  brillo::FlagHelper::Init(
      argc, argv,
      "Print information obtained from /sys about the power supply.");
  base::AtExitManager at_exit_manager;
  base::MessageLoopForIO message_loop;
  logging::SetMinLogLevel(logging::LOG_WARNING);

  power_manager::Prefs prefs;
  CHECK(prefs.Init(power_manager::Prefs::GetDefaultStore(),
                   power_manager::Prefs::GetDefaultSources()));

  power_manager::system::UdevStub udev;
  power_manager::system::DBusWrapperStub dbus_wrapper;
  base::FilePath path(power_manager::kPowerStatusPath);
  power_manager::system::PowerSupply power_supply;
  power_supply.Init(path, &prefs, &udev, &dbus_wrapper);

  CHECK(power_supply.RefreshImmediately());
  const PowerStatus status = power_supply.GetPowerStatus();

  // NOTE, autotests (see autotest/files/client/cros/power_status.py) rely on
  // parsing this information below.
  // DO NOT CHANGE formatting without also fixing there as well.
  InfoDisplay display;
  display.SetIndent(0, 0);
  display.PrintString("Device: Line Power");
  display.SetIndent(2, kFieldNameColumns);
  display.PrintValue("path", status.line_power_path);
  display.PrintStringValue("online", BoolToString(status.line_power_on));
  display.PrintStringValue("type", status.line_power_type);
  switch (status.external_power) {
    case power_manager::PowerSupplyProperties_ExternalPower_AC:
      display.PrintStringValue("enum type", "AC");
      break;
    case power_manager::PowerSupplyProperties_ExternalPower_USB:
      display.PrintStringValue("enum type", "USB");
      break;
    case power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED:
      display.PrintStringValue("enum type", "Disconnected");
      break;
    default:
      display.PrintStringValue("enum type", "Unknown");
  }

  if (status.has_line_power_voltage)
    display.PrintValue("voltage (V)", status.line_power_voltage);
  else
    display.PrintValue("voltage (V)", "unknown");

  if (status.has_line_power_current)
    display.PrintValue("current (A)", status.line_power_current);
  else
    display.PrintValue("current (A)", "unknown");

  display.PrintValue("max voltage (V)", status.line_power_max_voltage);
  display.PrintValue("max current (A)", status.line_power_max_current);

  display.PrintStringValue("active source", status.external_power_source_id);
  std::vector<std::string> sources;
  for (const auto& port : status.ports) {
    if (port.role == PowerStatus::Port::Role::DEDICATED_SOURCE ||
        port.role == PowerStatus::Port::Role::DUAL_ROLE) {
      sources.push_back(base::StringPrintf(
          "%s%s [%s/%s]", port.id.c_str(), port.active_by_default ? "*" : "",
          port.manufacturer_id.c_str(), port.model_id.c_str()));
    }
  }
  display.PrintStringValue("available sources",
                           base::JoinString(sources, ", "));

  display.PrintStringValue("supports dual-role",
                           BoolToString(status.supports_dual_role_devices));

  if (status.battery_is_present) {
    display.SetIndent(0, 0);
    display.PrintString("Device: Battery");
    display.SetIndent(2, kFieldNameColumns);
    display.PrintValue("path", status.battery_path);
    display.PrintStringValue("vendor", status.battery_vendor);
    display.PrintStringValue("model name", status.battery_model_name);

    switch (status.battery_state) {
      case power_manager::PowerSupplyProperties_BatteryState_FULL:
        display.PrintStringValue("state", "Fully charged");
        break;
      case power_manager::PowerSupplyProperties_BatteryState_CHARGING:
        display.PrintStringValue("state", "Charging");
        break;
      case power_manager::PowerSupplyProperties_BatteryState_DISCHARGING:
        display.PrintStringValue("state", "Discharging");
        break;
      case power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT:
        display.PrintStringValue("state", "Not present");
        break;
      default:
        display.PrintStringValue("state", "Unknown");
    }

    display.PrintValue("voltage (V)", status.battery_voltage);
    display.PrintValue("energy (Wh)", status.battery_energy);
    display.PrintValue("energy rate (W)", status.battery_energy_rate);
    display.PrintValue("current (A)", status.battery_current);
    display.PrintValue("charge (Ah)", status.battery_charge);
    display.PrintValue("full charge (Ah)", status.battery_charge_full);
    display.PrintValue("full charge design (Ah)",
                       status.battery_charge_full_design);
    display.PrintValue("percentage", status.battery_percentage);
    display.PrintValue("display percentage", status.display_battery_percentage);
    display.PrintStringValue("technology", status.battery_technology);

    // Don't print the battery time estimates -- they're wildly inaccurate since
    // this program only takes a single reading of the current.
  }
  return 0;
}
