// 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() 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_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

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

  ~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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SuspendDelayControllerTest);
};

}  // 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());

  observer_.set_timeout(kDarkResumeMinDelay);
  // 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
