// Copyright 2019 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 "vm_tools/concierge/power_manager_client.h"

#include <stdint.h>

#include <memory>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/memory/ref_counted.h>
#include <base/test/task_environment.h>
#include <base/threading/sequenced_task_runner_handle.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/object_path.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <power_manager/proto_bindings/suspend.pb.h>

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

namespace vm_tools {
namespace concierge {
namespace {

void SetTrue(bool* flag) {
  *flag = true;
}

void Increment(int32_t* counter) {
  *counter += 1;
}

class PowerManagerClientTest : public ::testing::Test {
 public:
  PowerManagerClientTest() = default;

  void SetUp() override {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    mock_bus_ = new dbus::MockBus(options);

    power_manager_proxy_ = new dbus::MockObjectProxy(
        mock_bus_.get(), power_manager::kPowerManagerServiceName,
        dbus::ObjectPath(power_manager::kPowerManagerServicePath));

    // Sets an expectation that the mock proxy's CallMethodAndBlock() will use
    // CreateMockProxyResponse() to return responses.
    EXPECT_CALL(*power_manager_proxy_.get(), CallMethodAndBlock(_, _))
        .WillRepeatedly(
            Invoke(this, &PowerManagerClientTest::CreateMockProxyResponse));

    // Set an expectation so that the MockBus will return our mock power manager
    // proxy.
    EXPECT_CALL(*mock_bus_.get(),
                GetObjectProxy(
                    power_manager::kPowerManagerServiceName,
                    dbus::ObjectPath(power_manager::kPowerManagerServicePath)))
        .WillOnce(Return(power_manager_proxy_.get()));

    EXPECT_CALL(*mock_bus_, GetDBusTaskRunner())
        .WillRepeatedly(Return(base::SequencedTaskRunnerHandle::Get().get()));
  }

 protected:
  std::unique_ptr<dbus::Response> CreateMockProxyResponse(
      dbus::MethodCall* method_call, int timeout_ms) {
    if (method_call->GetInterface() != power_manager::kPowerManagerInterface) {
      LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
      return std::unique_ptr<dbus::Response>();
    }

    std::unique_ptr<dbus::Response> response = dbus::Response::CreateEmpty();
    if (method_call->GetMember() ==
        power_manager::kRegisterSuspendDelayMethod) {
      power_manager::RegisterSuspendDelayReply reply;
      reply.set_delay_id(delay_id_);

      if (!dbus::MessageWriter(response.get())
               .AppendProtoAsArrayOfBytes(reply)) {
        LOG(ERROR) << "Failed to encode RegisterSuspendDelayReply";
      }
    } else if (method_call->GetMember() ==
               power_manager::kHandleSuspendReadinessMethod) {
      power_manager::SuspendReadinessInfo info;
      if (!dbus::MessageReader(method_call).PopArrayOfBytesAsProto(&info)) {
        LOG(ERROR) << "Failed to decode SuspendReadinessInfo";
        return std::unique_ptr<dbus::Response>();
      }

      reported_delay_id_ = info.delay_id();
      reported_suspend_id_ = info.suspend_id();
    } else if (method_call->GetMember() ==
               power_manager::kUnregisterSuspendDelayMethod) {
      unregistered_ = true;
    }

    return response;
  }

  base::test::TaskEnvironment task_environment_;

  scoped_refptr<dbus::MockBus> mock_bus_;
  scoped_refptr<dbus::MockObjectProxy> power_manager_proxy_;

  // Tests may change these values but the defaults should also be valid.
  int32_t delay_id_{7};
  int32_t current_suspend_id_{11};

  // Set in CreateMockProxyResponse().
  int32_t reported_delay_id_{-1};
  int32_t reported_suspend_id_{-1};
  bool unregistered_{false};
};

}  // namespace

// Tests that PowerManagerClient notifies powerd that it is ready to suspend
// once the registered callback returns.
TEST_F(PowerManagerClientTest, SuspendReadiness) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  delay_id_ = 19;
  current_suspend_id_ = 13;

  client->RegisterSuspendDelay(base::DoNothing(), base::DoNothing());

  dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent message;
  message.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                  .AppendProtoAsArrayOfBytes(message));

  client->HandleSuspendImminent(&suspend_imminent);

  EXPECT_EQ(delay_id_, reported_delay_id_);
  EXPECT_EQ(current_suspend_id_, reported_suspend_id_);
}

// Tests that the PowerManagerClient unregisters its suspend delay when it is
// destroyed.
TEST_F(PowerManagerClientTest, Unregister) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  client->RegisterSuspendDelay(base::DoNothing(), base::DoNothing());
  client.reset();

  EXPECT_TRUE(unregistered_);
}

// Tests that the PowerManagerClient runs the provided callbacks when it
// receives a SuspendImminent signal.
TEST_F(PowerManagerClientTest, SuspendImminent) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  current_suspend_id_ = 1297;

  bool called = false;
  client->RegisterSuspendDelay(base::Bind(&SetTrue, &called),
                               base::DoNothing());

  dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent message;
  message.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                  .AppendProtoAsArrayOfBytes(message));

  client->HandleSuspendImminent(&suspend_imminent);

  EXPECT_TRUE(called);
}

// Tests that the PowerManagerClient runs the provided callbacks when it
// receives a SuspendDone signal.
TEST_F(PowerManagerClientTest, SuspendDone) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  current_suspend_id_ = 509;

  bool called = false;
  client->RegisterSuspendDelay(base::DoNothing(),
                               base::Bind(&SetTrue, &called));

  dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent imminent;
  imminent.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                  .AppendProtoAsArrayOfBytes(imminent));

  client->HandleSuspendImminent(&suspend_imminent);

  EXPECT_FALSE(called);

  dbus::Signal suspend_done(power_manager::kPowerManagerInterface,
                            power_manager::kSuspendDoneSignal);

  power_manager::SuspendDone done;
  done.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(
      dbus::MessageWriter(&suspend_done).AppendProtoAsArrayOfBytes(done));

  client->HandleSuspendDone(&suspend_done);

  EXPECT_TRUE(called);
}

// Tests that the PowerManagerClient ignores SuspendDone signals whose ids
// don't match the current suspend id.
TEST_F(PowerManagerClientTest, WrongSuspendId) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  current_suspend_id_ = 92;

  bool called = false;
  client->RegisterSuspendDelay(base::DoNothing(),
                               base::Bind(&SetTrue, &called));

  dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent imminent;
  imminent.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                  .AppendProtoAsArrayOfBytes(imminent));

  client->HandleSuspendImminent(&suspend_imminent);

  EXPECT_FALSE(called);

  dbus::Signal suspend_done(power_manager::kPowerManagerInterface,
                            power_manager::kSuspendDoneSignal);

  power_manager::SuspendDone done;
  done.set_suspend_id(current_suspend_id_ - 1);
  ASSERT_TRUE(
      dbus::MessageWriter(&suspend_done).AppendProtoAsArrayOfBytes(done));

  client->HandleSuspendDone(&suspend_done);

  EXPECT_FALSE(called);
}

// Tests that the PowerManagerClient runs the provided callbacks even if it
// receives multiple SuspendImminent signals before receiving a SuspendDone.
TEST_F(PowerManagerClientTest, MultipleSuspendImminents) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  current_suspend_id_ = 7261;

  int32_t counter = 0;
  client->RegisterSuspendDelay(base::Bind(&Increment, &counter),
                               base::DoNothing());

  for (int i = 0; i < 3; ++i) {
    ++current_suspend_id_;

    dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                  power_manager::kSuspendImminentSignal);

    power_manager::SuspendImminent imminent;
    imminent.set_suspend_id(current_suspend_id_);
    ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                    .AppendProtoAsArrayOfBytes(imminent));

    client->HandleSuspendImminent(&suspend_imminent);

    EXPECT_EQ(i + 1, counter);
  }
}

// Tests that PowerManagerClient re-registers its suspend delay and uses the
// new delay id if powerd restarts.
TEST_F(PowerManagerClientTest, NameOwnerChanged) {
  std::unique_ptr<PowerManagerClient> client =
      std::make_unique<PowerManagerClient>(mock_bus_);

  // Register the suspend delay and do one suspend.
  delay_id_ = 189;
  client->RegisterSuspendDelay(base::DoNothing(), base::DoNothing());

  dbus::Signal suspend_imminent(power_manager::kPowerManagerInterface,
                                power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent message;
  message.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent)
                  .AppendProtoAsArrayOfBytes(message));

  client->HandleSuspendImminent(&suspend_imminent);

  EXPECT_EQ(delay_id_, reported_delay_id_);

  // Now pretend like powerd restarted and do another suspend.
  delay_id_ = 2678;
  client->HandleNameOwnerChanged("", "new_powerd");

  dbus::Signal suspend_imminent2(power_manager::kPowerManagerInterface,
                                 power_manager::kSuspendImminentSignal);

  power_manager::SuspendImminent message2;
  message2.set_suspend_id(current_suspend_id_);
  ASSERT_TRUE(dbus::MessageWriter(&suspend_imminent2)
                  .AppendProtoAsArrayOfBytes(message2));

  client->HandleSuspendImminent(&suspend_imminent2);

  EXPECT_EQ(delay_id_, reported_delay_id_);
}

}  // namespace concierge
}  // namespace vm_tools
