// 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/policy/suspend_delay_controller.h"

#include <base/compiler_specific.h>
#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "power_manager/common/test_main_loop_runner.h"
#include "power_manager/powerd/policy/suspend_delay_observer.h"
#include "power_manager/proto_bindings/suspend.pb.h"

namespace power_manager {
namespace policy {

namespace {

// Maximum amount of time to wait for OnReadyForSuspend() to be called.
const int kSuspendTimeoutMs = 5000;

class TestObserver : public SuspendDelayObserver {
 public:
  TestObserver()
      : timeout_(base::TimeDelta::FromMilliseconds(kSuspendTimeoutMs)) {}
  TestObserver(const TestObserver&) = delete;
  TestObserver& operator=(const TestObserver&) = delete;

  ~TestObserver() override {}

  // Must be called before RunUntilReadyForSuspend().
  void set_timeout(base::TimeDelta timeout) { timeout_ = timeout; }

  // Runs |loop_| until OnReadyForSuspend() is called.
  bool RunUntilReadyForSuspend() { return loop_runner_.StartLoop(timeout_); }

  // SuspendDelayObserver implementation:
  void OnReadyForSuspend(SuspendDelayController* controller,
                         int suspend_id) override {
    loop_runner_.StopLoop();
  }

 private:
  // Maximum time to wait for readiness.
  base::TimeDelta timeout_;

  TestMainLoopRunner loop_runner_;
};

class SuspendDelayControllerTest : public ::testing::Test {
 public:
  SuspendDelayControllerTest()
      : controller_(
            1, "", SuspendDelayController::kDefaultMaxSuspendDelayTimeout) {
    controller_.AddObserver(&observer_);
  }
  SuspendDelayControllerTest(const SuspendDelayControllerTest&) = delete;
  SuspendDelayControllerTest& operator=(const SuspendDelayControllerTest&) =
      delete;

  ~SuspendDelayControllerTest() override {
    controller_.RemoveObserver(&observer_);
  }

 protected:
  // Calls |controller_|'s RegisterSuspendDelay() method and returns the
  // newly-created delay's ID.
  int RegisterSuspendDelay(base::TimeDelta timeout, const std::string& client) {
    RegisterSuspendDelayRequest request;
    request.set_timeout(timeout.ToInternalValue());
    request.set_description(client + "-desc");
    RegisterSuspendDelayReply reply;
    controller_.RegisterSuspendDelay(request, client, &reply);
    return reply.delay_id();
  }

  // Calls |controller_|'s UnregisterSuspendDelay() method.
  void UnregisterSuspendDelay(int delay_id, const std::string& client) {
    UnregisterSuspendDelayRequest request;
    request.set_delay_id(delay_id);
    controller_.UnregisterSuspendDelay(request, client);
  }

  // Calls |controller_|'s HandleSuspendReadiness() method.
  void HandleSuspendReadiness(int delay_id,
                              int suspend_id,
                              const std::string& client) {
    SuspendReadinessInfo info;
    info.set_delay_id(delay_id);
    info.set_suspend_id(suspend_id);
    controller_.HandleSuspendReadiness(info, client);
  }

  TestObserver observer_;
  SuspendDelayController controller_;
};

}  // namespace

TEST_F(SuspendDelayControllerTest, NoDelays) {
  // The controller should say that it's initially ready to suspend when no
  // delays have been registered.
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The controller should still say that it's ready to suspend after we request
  // suspending -- there are no delays to wait for.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The observer should be notified that it's safe to suspend.
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, SingleDelay) {
  // Register a delay.
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // A SuspendImminent signal should be emitted after suspending is requested.
  // The controller shouldn't report readiness now; it's waiting on the delay.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // Tell the controller that the delay is ready and check that the controller
  // reports readiness now.
  HandleSuspendReadiness(delay_id, kSuspendId, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, CheckMinTimeout) {
  // Request maximum delay.
  const std::string kClient = "client";
  RegisterSuspendDelayRequest request;
  request.set_timeout(-1);
  request.set_description(kClient + "-desc");
  RegisterSuspendDelayReply reply;
  controller_.RegisterSuspendDelay(request, kClient, &reply);

  // A valid delay id should be returned and |min_delay_timeout_ms| should be
  // the maximum suspend delay timeout as a negative timeout was sent in the
  // request.
  EXPECT_GT(reply.delay_id(), 0);
  EXPECT_EQ(
      reply.min_delay_timeout_ms(),
      SuspendDelayController::kDefaultMaxSuspendDelayTimeout.InMilliseconds());
}

TEST_F(SuspendDelayControllerTest, UnregisterDelayBeforeRequestingSuspend) {
  // Register a delay, but unregister it immediately.
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  UnregisterSuspendDelay(delay_id, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The controller should immediately report readiness.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, UnregisterDelayAfterRequestingSuspend) {
  // Register a delay.
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // Request suspending.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // If the delay is unregistered while the controller is waiting for it, the
  // controller should start reporting readiness.
  UnregisterSuspendDelay(delay_id, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, RegisterDelayAfterRequestingSuspend) {
  // Request suspending before any delays have been registered.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // Register a delay now.  The controller should still report readiness.
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // Request suspending again.  The controller should say it isn't ready now.
  const int kNextSuspendId = 6;
  controller_.PrepareForSuspend(kNextSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  HandleSuspendReadiness(delay_id, kNextSuspendId, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, Timeout) {
  // Register a delay with a short timeout.
  const std::string kClient = "client";
  RegisterSuspendDelay(base::TimeDelta::FromMilliseconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The controller should report readiness due to the timeout being hit.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, FinishRequest) {
  const std::string kClient = "client";
  RegisterSuspendDelay(base::TimeDelta::FromMilliseconds(1), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // FinishSuspend() calls with bogus IDs should be ignored.
  controller_.FinishSuspend(kSuspendId - 1);
  controller_.FinishSuspend(kSuspendId + 1);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // The controller should report that the system is ready to suspend as soon as
  // the suspend request is cancelled.
  controller_.FinishSuspend(kSuspendId);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The timer should also be stopped.
  observer_.set_timeout(base::TimeDelta::FromMilliseconds(2));
  EXPECT_FALSE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, DisconnectClientBeforeRequestingSuspend) {
  // Register a delay, but immediately tell the controller that the D-Bus client
  // that registered the delay has disconnected.
  const std::string kClient = "client";
  RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  controller_.HandleDBusClientDisconnected(kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // The delay should have been removed.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, DisconnectClientAfterRequestingSuspend) {
  const std::string kClient = "client";
  RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // If the client is disconnected while the controller is waiting, it should
  // report readiness.
  controller_.HandleDBusClientDisconnected(kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, MultipleSuspendRequests) {
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // Request suspending.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // Before confirming that the delay is ready, request suspending again.
  const int kNextSuspendId = 6;
  controller_.PrepareForSuspend(kNextSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // Report readiness, but do it on behalf of the original suspend attempt.  The
  // controller shouldn't say it's ready yet.
  HandleSuspendReadiness(delay_id, kSuspendId, kClient);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // Now report readiness on behalf of the second suspend attempt.
  HandleSuspendReadiness(delay_id, kNextSuspendId, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

TEST_F(SuspendDelayControllerTest, MultipleDelays) {
  // Register two delays.
  const std::string kClient1 = "client1";
  int delay_id1 =
      RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient1);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  const std::string kClient2 = "client2";
  int delay_id2 =
      RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient2);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // After getting a suspend request, the controller shouldn't report readiness
  // until both delays have confirmed their readiness.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, false);
  EXPECT_FALSE(controller_.ReadyForSuspend());
  HandleSuspendReadiness(delay_id2, kSuspendId, kClient2);
  EXPECT_FALSE(controller_.ReadyForSuspend());
  HandleSuspendReadiness(delay_id1, kSuspendId, kClient1);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

// Controller should wait for |kDarkResumeMinDelay| on dark resume when no
// additional delays are registered.
TEST_F(SuspendDelayControllerTest, DarkResumeNoExternalDelays) {
  // The controller should say that it's initially ready to suspend when no
  // delays have been registered.
  EXPECT_TRUE(controller_.ReadyForSuspend());

  const int kSuspendId = 5;
  const base::TimeDelta kDarkResumeMinDelay =
      base::TimeDelta::FromMilliseconds(5);
  // The minimum delay controller is expected to wait when in dark resume before
  // saying it is ready for suspend.
  controller_.set_dark_resume_min_delay_for_testing(kDarkResumeMinDelay);

  controller_.PrepareForSuspend(kSuspendId, true);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // The observer should be notified that it's safe to suspend after
  // |kDarkResumeMinDelay| since no other delays are registered.
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

// When a client requests a delay greater than |kDarkResumeMinDelay| controller
// should wait for the client readiness (or its timeout) before saying it is
// ready for suspend.
TEST_F(SuspendDelayControllerTest, DarkResumeSingleDelay) {
  // Register a delay.
  const std::string kClient = "client";
  int delay_id = RegisterSuspendDelay(base::TimeDelta::FromSeconds(8), kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());

  // Set dark resume min delay to 5 milliseconds.
  const base::TimeDelta kDarkResumeMinDelay =
      base::TimeDelta::FromMilliseconds(5);
  controller_.set_dark_resume_min_delay_for_testing(kDarkResumeMinDelay);

  // The controller shouldn't report readiness now; it's waiting on the both
  // |kDarkResumeMinDelay| and registered client delay.
  const int kSuspendId = 5;
  controller_.PrepareForSuspend(kSuspendId, true);
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // The observers should not be notified after |kDarkResumeMinDelay| as the
  // registered client is not yet ready.
  observer_.set_timeout(kDarkResumeMinDelay);
  EXPECT_FALSE(observer_.RunUntilReadyForSuspend());
  EXPECT_FALSE(controller_.ReadyForSuspend());

  // Tell the controller that registered client is ready and check that the
  // controller reports readiness now.
  HandleSuspendReadiness(delay_id, kSuspendId, kClient);
  EXPECT_TRUE(controller_.ReadyForSuspend());
  EXPECT_TRUE(observer_.RunUntilReadyForSuspend());
  EXPECT_TRUE(controller_.ReadyForSuspend());
}

}  // namespace policy
}  // namespace power_manager
