// Copyright 2018 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 "shill/power_manager.h"

#include <string>

#include <base/bind.h>
#include <chromeos/dbus/service_constants.h>

#include "shill/control_interface.h"
#include "shill/logging.h"
#include "shill/power_manager_proxy_interface.h"

using base::Bind;
using base::TimeDelta;
using base::Unretained;

namespace shill {

// static
const int PowerManager::kInvalidSuspendId = -1;
const char PowerManager::kSuspendDelayDescription[] = "shill";
const char PowerManager::kDarkSuspendDelayDescription[] = "shill";
const int PowerManager::kSuspendTimeoutMilliseconds = 15 * 1000;

PowerManager::PowerManager(ControlInterface* control_interface)
    : control_interface_(control_interface),
      suspend_delay_registered_(false),
      suspend_delay_id_(0),
      dark_suspend_delay_registered_(false),
      dark_suspend_delay_id_(0),
      suspending_(false),
      suspend_ready_(false),
      suspend_done_deferred_(false),
      in_dark_resume_(false),
      current_suspend_id_(0),
      current_dark_suspend_id_(0),
      suspend_duration_us_(0) {}

PowerManager::~PowerManager() = default;

void PowerManager::Start(
    TimeDelta suspend_delay,
    const SuspendImminentCallback& suspend_imminent_callback,
    const SuspendDoneCallback& suspend_done_callback,
    const DarkSuspendImminentCallback& dark_suspend_imminent_callback) {
  power_manager_proxy_ = control_interface_->CreatePowerManagerProxy(
      this, Bind(&PowerManager::OnPowerManagerAppeared, Unretained(this)),
      Bind(&PowerManager::OnPowerManagerVanished, Unretained(this)));
  suspend_delay_ = suspend_delay;
  suspend_imminent_callback_ = suspend_imminent_callback;
  suspend_done_callback_ = suspend_done_callback;
  dark_suspend_imminent_callback_ = dark_suspend_imminent_callback;
}

void PowerManager::Stop() {
  LOG(INFO) << __func__;
  // We may attempt to unregister with a stale |suspend_delay_id_| if powerd
  // reappeared behind our back. It is safe to do so.
  if (suspend_delay_registered_)
    power_manager_proxy_->UnregisterSuspendDelay(suspend_delay_id_);
  if (dark_suspend_delay_registered_)
    power_manager_proxy_->UnregisterDarkSuspendDelay(dark_suspend_delay_id_);

  suspend_delay_registered_ = false;
  dark_suspend_delay_registered_ = false;
  power_manager_proxy_.reset();
}

bool PowerManager::ReportSuspendReadiness() {
  // If |suspend_done_deferred_| is true, a SuspendDone notification was
  // observed before SuspendReadiness was reported and no further
  // SuspendImminent notification was observed after the SuspendDone
  // notification. We don't need to report SuspendReadiness, but instead notify
  // the deferred SuspendDone.
  if (suspend_done_deferred_) {
    LOG(INFO) << __func__ << ": Notifying deferred SuspendDone.";
    NotifySuspendDone();
    return false;
  }

  suspend_ready_ = true;
  if (!suspending_) {
    LOG(INFO) << __func__ << ": Suspend attempt (" << current_suspend_id_
              << ") not active. Ignoring signal.";
    return false;
  }
  return power_manager_proxy_->ReportSuspendReadiness(suspend_delay_id_,
                                                      current_suspend_id_);
}

bool PowerManager::ReportDarkSuspendReadiness() {
  return power_manager_proxy_->ReportDarkSuspendReadiness(
      dark_suspend_delay_id_, current_dark_suspend_id_);
}

bool PowerManager::RecordDarkResumeWakeReason(const std::string& wake_reason) {
  return power_manager_proxy_->RecordDarkResumeWakeReason(wake_reason);
}

void PowerManager::OnSuspendImminent(int suspend_id) {
  LOG(INFO) << __func__ << "(" << suspend_id << ")";
  current_suspend_id_ = suspend_id;

  // Ignore any previously deferred SuspendDone notification as we're going to
  // suspend again and expect a new SuspendDone notification later.
  suspend_done_deferred_ = false;

  // If we're already suspending, don't call the |suspend_imminent_callback_|
  // again.
  if (!suspending_) {
    // Change the power state to suspending as soon as this signal is received
    // so that the manager can suppress auto-connect, for example.
    // Also, we must set this before running the callback below, because the
    // callback may synchronously report suspend readiness.
    suspending_ = true;
    suspend_duration_us_ = 0;
    suspend_imminent_callback_.Run();
  }
}

void PowerManager::OnSuspendDone(int suspend_id, int64_t suspend_duration_us) {
  // NB: |suspend_id| could be -1. See OnPowerManagerVanished.
  LOG(INFO) << __func__ << "(" << suspend_id << ")";
  if (!suspending_) {
    LOG(WARNING) << "Received unexpected SuspendDone (" << suspend_id
                 << "). Ignoring.";
    return;
  }

  suspend_duration_us_ = suspend_duration_us;

  if (!suspend_ready_) {
    LOG(INFO) << "Received SuspendDone (" << suspend_id
              << ") before SuspendReadiness is reported. "
              << "Defer SuspendDone notification.";
    suspend_done_deferred_ = true;
    return;
  }

  NotifySuspendDone();
}

void PowerManager::NotifySuspendDone() {
  suspending_ = false;
  suspend_ready_ = false;
  suspend_done_deferred_ = false;
  in_dark_resume_ = false;
  suspend_done_callback_.Run();
}

void PowerManager::OnDarkSuspendImminent(int suspend_id) {
  LOG(INFO) << __func__ << "(" << suspend_id << ")";
  if (!dark_suspend_delay_registered_) {
    LOG(WARNING) << "Ignoring DarkSuspendImminent signal from powerd. shill "
                 << "does not have a dark suspend delay registered. This "
                 << "means that shill is not guaranteed any time before a "
                 << "resuspend.";
    return;
  }
  in_dark_resume_ = true;
  current_dark_suspend_id_ = suspend_id;
  dark_suspend_imminent_callback_.Run();
}

void PowerManager::OnPowerManagerAppeared() {
  LOG(INFO) << __func__;

  // This function could get called twice in a row due to races in
  // ObjectProxy.
  if (suspend_delay_registered_) {
    return;
  }

  if (power_manager_proxy_->RegisterSuspendDelay(
          suspend_delay_, kSuspendDelayDescription, &suspend_delay_id_))
    suspend_delay_registered_ = true;

  if (power_manager_proxy_->RegisterDarkSuspendDelay(
          suspend_delay_, kDarkSuspendDelayDescription,
          &dark_suspend_delay_id_))
    dark_suspend_delay_registered_ = true;
}

void PowerManager::OnPowerManagerVanished() {
  LOG(INFO) << __func__;
  // If powerd vanished during a suspend, we need to wake ourselves up.
  if (suspending_) {
    suspend_ready_ = true;
    OnSuspendDone(kInvalidSuspendId, 0);
  }
  suspend_delay_registered_ = false;
  dark_suspend_delay_registered_ = false;
}

}  // namespace shill
