// 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 "power_manager/powerd/metrics_collector.h"

#include <stdint.h>

#include <algorithm>
#include <cmath>

#include <base/logging.h>

#include "power_manager/common/metrics_constants.h"
#include "power_manager/common/metrics_sender.h"
#include "power_manager/common/prefs.h"
#include "power_manager/common/util.h"
#include "power_manager/powerd/policy/backlight_controller.h"

namespace power_manager {

using system::PowerStatus;

namespace metrics {
namespace {

// Generates the histogram name under which dark resume wake duration metrics
// are logged for the dark resume triggered by |wake_reason|.
std::string WakeReasonToHistogramName(const std::string& wake_reason) {
  return std::string("Power.DarkResumeWakeDurationMs.").append(wake_reason);
}

// Returns true if port |index| exists in |status| and has a connected dedicated
// source or dual-role device.
bool ChargingPortConnected(const PowerStatus& status, size_t index) {
  if (index >= status.ports.size())
    return false;

  const PowerStatus::Port::Role role = status.ports[index].role;
  return role == PowerStatus::Port::Role::DEDICATED_SOURCE ||
         role == PowerStatus::Port::Role::DUAL_ROLE;
}

// Returns a value describing which power ports are connected.
ConnectedChargingPorts GetConnectedChargingPorts(const PowerStatus& status) {
  // TODO(derat): Add more values if we ship systems with more than two ports.
  if (status.ports.size() > 2u)
    return ConnectedChargingPorts::TOO_MANY_PORTS;

  const bool port1_connected = ChargingPortConnected(status, 0);
  const bool port2_connected = ChargingPortConnected(status, 1);
  if (port1_connected && port2_connected)
    return ConnectedChargingPorts::PORT1_PORT2;
  else if (port1_connected)
    return ConnectedChargingPorts::PORT1;
  else if (port2_connected)
    return ConnectedChargingPorts::PORT2;
  else
    return ConnectedChargingPorts::NONE;
}

}  // namespace

// static
std::string MetricsCollector::AppendPowerSourceToEnumName(
    const std::string& enum_name, PowerSource power_source) {
  return enum_name +
         (power_source == PowerSource::AC ? kAcSuffix : kBatterySuffix);
}

MetricsCollector::MetricsCollector() = default;

MetricsCollector::~MetricsCollector() = default;

void MetricsCollector::Init(
    PrefsInterface* prefs,
    policy::BacklightController* display_backlight_controller,
    policy::BacklightController* keyboard_backlight_controller,
    const PowerStatus& power_status) {
  prefs_ = prefs;
  display_backlight_controller_ = display_backlight_controller;
  keyboard_backlight_controller_ = keyboard_backlight_controller;
  last_power_status_ = power_status;

  if (display_backlight_controller_ || keyboard_backlight_controller_) {
    generate_backlight_metrics_timer_.Start(
        FROM_HERE, base::TimeDelta::FromMilliseconds(kBacklightLevelIntervalMs),
        this, &MetricsCollector::GenerateBacklightLevelMetrics);
  }
}

void MetricsCollector::HandleScreenDimmedChange(
    bool dimmed, base::TimeTicks last_user_activity_time) {
  if (dimmed) {
    base::TimeTicks now = clock_.GetCurrentTime();
    screen_dim_timestamp_ = now;
    last_idle_event_timestamp_ = now;
    last_idle_timedelta_ = now - last_user_activity_time;
  } else {
    screen_dim_timestamp_ = base::TimeTicks();
  }
}

void MetricsCollector::HandleScreenOffChange(
    bool off, base::TimeTicks last_user_activity_time) {
  if (off) {
    base::TimeTicks now = clock_.GetCurrentTime();
    screen_off_timestamp_ = now;
    last_idle_event_timestamp_ = now;
    last_idle_timedelta_ = now - last_user_activity_time;
  } else {
    screen_off_timestamp_ = base::TimeTicks();
  }
}

void MetricsCollector::HandleSessionStateChange(SessionState state) {
  if (state == session_state_)
    return;

  session_state_ = state;

  switch (state) {
    case SessionState::STARTED:
      session_start_time_ = clock_.GetCurrentTime();
      if (!last_power_status_.line_power_on)
        IncrementNumOfSessionsPerChargeMetric();
      if (last_power_status_.battery_is_present) {
        // Enum to avoid exponential histogram's varyingly-sized buckets.
        SendEnumMetricWithPowerSource(
            kBatteryRemainingAtStartOfSessionName,
            static_cast<int>(round(last_power_status_.battery_percentage)),
            kMaxPercent);
      }
      break;
    case SessionState::STOPPED: {
      if (last_power_status_.battery_is_present) {
        // Enum to avoid exponential histogram's varyingly-sized buckets.
        SendEnumMetricWithPowerSource(
            kBatteryRemainingAtEndOfSessionName,
            static_cast<int>(round(last_power_status_.battery_percentage)),
            kMaxPercent);
      }

      SendMetric(kLengthOfSessionName,
                 (clock_.GetCurrentTime() - session_start_time_).InSeconds(),
                 kLengthOfSessionMin, kLengthOfSessionMax, kDefaultBuckets);

      if (display_backlight_controller_) {
        SendMetric(kNumberOfAlsAdjustmentsPerSessionName,
                   display_backlight_controller_
                       ->GetNumAmbientLightSensorAdjustments(),
                   kNumberOfAlsAdjustmentsPerSessionMin,
                   kNumberOfAlsAdjustmentsPerSessionMax, kDefaultBuckets);
        SendMetricWithPowerSource(
            kUserBrightnessAdjustmentsPerSessionName,
            display_backlight_controller_->GetNumUserAdjustments(),
            kUserBrightnessAdjustmentsPerSessionMin,
            kUserBrightnessAdjustmentsPerSessionMax, kDefaultBuckets);
      }
      break;
    }
  }
}

void MetricsCollector::HandlePowerStatusUpdate(const PowerStatus& status) {
  const bool previously_on_line_power = last_power_status_.line_power_on;
  const bool previously_using_unknown_type =
      previously_on_line_power &&
      system::GetPowerSupplyTypeMetric(last_power_status_.line_power_type) ==
          PowerSupplyType::OTHER;

  last_power_status_ = status;

  // Charge stats.
  if (status.line_power_on && !previously_on_line_power) {
    GenerateNumOfSessionsPerChargeMetric();
    if (status.battery_is_present) {
      // Enum to avoid exponential histogram's varyingly-sized buckets.
      SendEnumMetric(kBatteryRemainingWhenChargeStartsName,
                     static_cast<int>(round(status.battery_percentage)),
                     kMaxPercent);
      SendEnumMetric(kBatteryChargeHealthName,
                     static_cast<int>(round(100.0 * status.battery_charge_full /
                                            status.battery_charge_full_design)),
                     kBatteryChargeHealthMax);
    }
  } else if (!status.line_power_on && previously_on_line_power) {
    if (session_state_ == SessionState::STARTED)
      IncrementNumOfSessionsPerChargeMetric();
  }

  // Power supply details.
  if (status.line_power_on) {
    const PowerSupplyType type =
        system::GetPowerSupplyTypeMetric(status.line_power_type);
    if (type == PowerSupplyType::OTHER && !previously_using_unknown_type)
      LOG(WARNING) << "Unknown power supply type " << status.line_power_type;
    SendEnumMetric(kPowerSupplyTypeName, static_cast<int>(type),
                   static_cast<int>(PowerSupplyType::MAX));

    // Sent as enums to avoid exponential histogram's exponentially-sized
    // buckets.
    SendEnumMetric(kPowerSupplyMaxVoltageName,
                   static_cast<int>(round(status.line_power_max_voltage)),
                   kPowerSupplyMaxVoltageMax);
    SendEnumMetric(kPowerSupplyMaxPowerName,
                   static_cast<int>(round(status.line_power_max_voltage *
                                          status.line_power_max_current)),
                   kPowerSupplyMaxPowerMax);
  }

  SendEnumMetric(kConnectedChargingPortsName,
                 static_cast<int>(GetConnectedChargingPorts(status)),
                 static_cast<int>(ConnectedChargingPorts::MAX));

  GenerateBatteryDischargeRateMetric();
  GenerateBatteryDischargeRateWhileSuspendedMetric();

  SendEnumMetric(kBatteryInfoSampleName,
                 static_cast<int>(BatteryInfoSampleResult::READ),
                 static_cast<int>(BatteryInfoSampleResult::MAX));
  // TODO(derat): Continue sending BAD in some situations? Remove this metric
  // entirely?
  SendEnumMetric(kBatteryInfoSampleName,
                 static_cast<int>(BatteryInfoSampleResult::GOOD),
                 static_cast<int>(BatteryInfoSampleResult::MAX));
}

void MetricsCollector::HandleShutdown(ShutdownReason reason) {
  SendEnumMetric(kShutdownReasonName, static_cast<int>(reason),
                 static_cast<int>(kShutdownReasonMax));
}

void MetricsCollector::PrepareForSuspend() {
  battery_energy_before_suspend_ = last_power_status_.battery_energy;
  on_line_power_before_suspend_ = last_power_status_.line_power_on;
  time_before_suspend_ = clock_.GetCurrentWallTime();
}

void MetricsCollector::HandleResume(int num_suspend_attempts) {
  SendMetric(kSuspendAttemptsBeforeSuccessName, num_suspend_attempts,
             kSuspendAttemptsMin, kSuspendAttemptsMax, kSuspendAttemptsBuckets);
  // Report the discharge rate in response to the next
  // OnPowerStatusUpdate() call.
  report_battery_discharge_rate_while_suspended_ = true;
}

void MetricsCollector::HandleCanceledSuspendRequest(int num_suspend_attempts) {
  SendMetric(kSuspendAttemptsBeforeCancelName, num_suspend_attempts,
             kSuspendAttemptsMin, kSuspendAttemptsMax, kSuspendAttemptsBuckets);
}

void MetricsCollector::GenerateDarkResumeMetrics(
    const std::vector<policy::Suspender::DarkResumeInfo>& wake_durations,
    base::TimeDelta suspend_duration) {
  if (suspend_duration.InSeconds() <= 0)
    return;

  // We want to get metrics even if the system suspended for less than an hour
  // so we scale the number of wakes up.
  static const int kSecondsPerHour = 60 * 60;
  const int64_t wakeups_per_hour =
      wake_durations.size() * kSecondsPerHour / suspend_duration.InSeconds();
  SendMetric(kDarkResumeWakeupsPerHourName, wakeups_per_hour,
             kDarkResumeWakeupsPerHourMin, kDarkResumeWakeupsPerHourMax,
             kDefaultBuckets);

  for (const auto& pair : wake_durations) {
    // Send aggregated dark resume duration metric.
    SendMetric(kDarkResumeWakeDurationMsName, pair.second.InMilliseconds(),
               kDarkResumeWakeDurationMsMin, kDarkResumeWakeDurationMsMax,
               kDefaultBuckets);
    // Send wake reason-specific dark resume duration metric.
    SendMetric(WakeReasonToHistogramName(pair.first),
               pair.second.InMilliseconds(), kDarkResumeWakeDurationMsMin,
               kDarkResumeWakeDurationMsMax, kDefaultBuckets);
  }
}

void MetricsCollector::GenerateUserActivityMetrics() {
  if (last_idle_event_timestamp_.is_null())
    return;

  base::TimeTicks current_time = clock_.GetCurrentTime();
  base::TimeDelta event_delta = current_time - last_idle_event_timestamp_;
  base::TimeDelta total_delta = event_delta + last_idle_timedelta_;
  last_idle_event_timestamp_ = base::TimeTicks();

  SendMetricWithPowerSource(kIdleName, total_delta.InMilliseconds(), kIdleMin,
                            kIdleMax, kDefaultBuckets);

  if (!screen_dim_timestamp_.is_null()) {
    base::TimeDelta dim_event_delta = current_time - screen_dim_timestamp_;
    SendMetricWithPowerSource(
        kIdleAfterDimName, dim_event_delta.InMilliseconds(), kIdleAfterDimMin,
        kIdleAfterDimMax, kDefaultBuckets);
    screen_dim_timestamp_ = base::TimeTicks();
  }
  if (!screen_off_timestamp_.is_null()) {
    base::TimeDelta screen_off_event_delta =
        current_time - screen_off_timestamp_;
    SendMetricWithPowerSource(
        kIdleAfterScreenOffName, screen_off_event_delta.InMilliseconds(),
        kIdleAfterScreenOffMin, kIdleAfterScreenOffMax, kDefaultBuckets);
    screen_off_timestamp_ = base::TimeTicks();
  }
}

void MetricsCollector::GenerateBacklightLevelMetrics() {
  if (!screen_dim_timestamp_.is_null() || !screen_off_timestamp_.is_null())
    return;

  double percent = 0.0;
  if (display_backlight_controller_ &&
      display_backlight_controller_->GetBrightnessPercent(&percent)) {
    // Enum to avoid exponential histogram's varyingly-sized buckets.
    SendEnumMetricWithPowerSource(kBacklightLevelName, lround(percent),
                                  kMaxPercent);
  }
  if (keyboard_backlight_controller_ &&
      keyboard_backlight_controller_->GetBrightnessPercent(&percent)) {
    // Enum to avoid exponential histogram's varyingly-sized buckets.
    SendEnumMetric(kKeyboardBacklightLevelName, lround(percent), kMaxPercent);
  }
}

void MetricsCollector::HandlePowerButtonEvent(ButtonState state) {
  switch (state) {
    case ButtonState::DOWN:
      // Just keep track of the time when the button was pressed.
      if (!last_power_button_down_timestamp_.is_null()) {
        LOG(ERROR) << "Got power-button-down event while button was already "
                   << "down";
      }
      last_power_button_down_timestamp_ = clock_.GetCurrentTime();
      break;
    case ButtonState::UP: {
      // Metrics are sent after the button is released.
      if (last_power_button_down_timestamp_.is_null()) {
        LOG(ERROR) << "Got power-button-up event while button was already up";
      } else {
        base::TimeDelta delta =
            clock_.GetCurrentTime() - last_power_button_down_timestamp_;
        last_power_button_down_timestamp_ = base::TimeTicks();
        SendMetric(kPowerButtonDownTimeName, delta.InMilliseconds(),
                   kPowerButtonDownTimeMin, kPowerButtonDownTimeMax,
                   kDefaultBuckets);
      }
      break;
    }
    case ButtonState::REPEAT:
      // Ignore repeat events if we get them.
      break;
  }
}

void MetricsCollector::SendPowerButtonAcknowledgmentDelayMetric(
    base::TimeDelta delay) {
  SendMetric(kPowerButtonAcknowledgmentDelayName, delay.InMilliseconds(),
             kPowerButtonAcknowledgmentDelayMin,
             kPowerButtonAcknowledgmentDelayMax, kDefaultBuckets);
}

bool MetricsCollector::SendMetricWithPowerSource(
    const std::string& name, int sample, int min, int max, int num_buckets) {
  const std::string full_name = AppendPowerSourceToEnumName(
      name, last_power_status_.line_power_on ? PowerSource::AC
                                             : PowerSource::BATTERY);
  return SendMetric(full_name, sample, min, max, num_buckets);
}

bool MetricsCollector::SendEnumMetricWithPowerSource(const std::string& name,
                                                     int sample,
                                                     int max) {
  const std::string full_name = AppendPowerSourceToEnumName(
      name, last_power_status_.line_power_on ? PowerSource::AC
                                             : PowerSource::BATTERY);
  return SendEnumMetric(full_name, sample, max);
}

void MetricsCollector::GenerateBatteryDischargeRateMetric() {
  // The battery discharge rate metric is relevant and collected only
  // when running on battery.
  if (!last_power_status_.battery_is_present ||
      last_power_status_.line_power_on)
    return;

  // Converts the discharge rate from W to mW.
  int rate =
      static_cast<int>(round(last_power_status_.battery_energy_rate * 1000));
  if (rate <= 0)
    return;

  // Ensures that the metric is not generated too frequently.
  if (!last_battery_discharge_rate_metric_timestamp_.is_null() &&
      (clock_.GetCurrentTime() - last_battery_discharge_rate_metric_timestamp_)
              .InSeconds() < kBatteryDischargeRateIntervalSec) {
    return;
  }

  if (SendMetric(kBatteryDischargeRateName, rate, kBatteryDischargeRateMin,
                 kBatteryDischargeRateMax, kDefaultBuckets))
    last_battery_discharge_rate_metric_timestamp_ = clock_.GetCurrentTime();
}

void MetricsCollector::GenerateBatteryDischargeRateWhileSuspendedMetric() {
  // Do nothing unless this is the first time we're called after resuming.
  if (!report_battery_discharge_rate_while_suspended_)
    return;
  report_battery_discharge_rate_while_suspended_ = false;

  if (!last_power_status_.battery_is_present || on_line_power_before_suspend_ ||
      last_power_status_.line_power_on)
    return;

  base::TimeDelta elapsed_time =
      clock_.GetCurrentWallTime() - time_before_suspend_;
  if (elapsed_time.InSeconds() <
      kBatteryDischargeRateWhileSuspendedMinSuspendSec)
    return;

  double discharged_watt_hours =
      battery_energy_before_suspend_ - last_power_status_.battery_energy;
  double discharge_rate_watts =
      discharged_watt_hours / (elapsed_time.InSecondsF() / 3600);

  // Maybe the charger was connected while the system was suspended but
  // disconnected before it resumed.
  if (discharge_rate_watts < 0.0)
    return;

  SendMetric(kBatteryDischargeRateWhileSuspendedName,
             static_cast<int>(round(discharge_rate_watts * 1000)),
             kBatteryDischargeRateWhileSuspendedMin,
             kBatteryDischargeRateWhileSuspendedMax, kDefaultBuckets);
}

void MetricsCollector::IncrementNumOfSessionsPerChargeMetric() {
  int64_t num = 0;
  prefs_->GetInt64(kNumSessionsOnCurrentChargePref, &num);
  num = std::max(num, static_cast<int64_t>(0));
  prefs_->SetInt64(kNumSessionsOnCurrentChargePref, num + 1);
}

void MetricsCollector::GenerateNumOfSessionsPerChargeMetric() {
  int64_t sample = 0;
  prefs_->GetInt64(kNumSessionsOnCurrentChargePref, &sample);
  if (sample <= 0)
    return;

  sample = std::min(sample, static_cast<int64_t>(kNumOfSessionsPerChargeMax));
  prefs_->SetInt64(kNumSessionsOnCurrentChargePref, 0);
  SendMetric(kNumOfSessionsPerChargeName, sample, kNumOfSessionsPerChargeMin,
             kNumOfSessionsPerChargeMax, kDefaultBuckets);
}

}  // namespace metrics
}  // namespace power_manager
