// Copyright 2022 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 <memory>
#include <string>
#include <unordered_map>

#include <base/callback.h>
#include <base/check.h>
#include <base/memory/ref_counted.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/power_manager/dbus-constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "federated/power_supply_training_condition.h"
#include "power_manager/proto_bindings/power_supply_properties.pb.h"

namespace federated {
namespace {

using ::power_manager::kPowerManagerInterface;
using ::power_manager::kPowerSupplyPollSignal;
using ::testing::_;
using ::testing::SaveArg;
using ::testing::StrictMock;

// Generates a PowerSupplyProperties proto with the given battery percent and
// state.
power_manager::PowerSupplyProperties GeneratePowerSupplyProto(
    const double battery_percent,
    power_manager::PowerSupplyProperties::BatteryState battery_state) {
  power_manager::PowerSupplyProperties power_supply_proto;
  power_supply_proto.set_battery_percent(battery_percent);
  power_supply_proto.set_battery_state(battery_state);

  return power_supply_proto;
}

// Writes the given string (a serialized proto or "") to dbus signal.
void WriteSerializedProtoToSignal(const std::string& serialized_proto,
                                  dbus::Signal* signal) {
  dbus::MessageWriter writer(signal);
  writer.AppendArrayOfBytes(
      reinterpret_cast<const uint8_t*>(serialized_proto.data()),
      serialized_proto.size());
}

}  // namespace

class PowerSupplyTrainingConditionTest : public ::testing::Test {
 public:
  PowerSupplyTrainingConditionTest()
      : mock_dbus_(new StrictMock<dbus::MockBus>(dbus::Bus::Options())),
        dbus_object_proxy_(new StrictMock<dbus::MockObjectProxy>(
            mock_dbus_.get(),
            power_manager::kPowerManagerServiceName,
            dbus::ObjectPath(power_manager::kPowerManagerServicePath))) {}
  PowerSupplyTrainingConditionTest(const PowerSupplyTrainingConditionTest&) =
      delete;
  PowerSupplyTrainingConditionTest& operator=(
      const PowerSupplyTrainingConditionTest&) = delete;

  void SetUp() override {
    EXPECT_CALL(*mock_dbus_,
                GetObjectProxy(
                    power_manager::kPowerManagerServiceName,
                    dbus::ObjectPath(power_manager::kPowerManagerServicePath)))
        .WillOnce(Return(dbus_object_proxy_.get()));

    EXPECT_CALL(*dbus_object_proxy_,
                DoConnectToSignal(power_manager::kPowerManagerInterface,
                                  power_manager::kPowerSupplyPollSignal, _, _))
        .WillOnce(SaveArg<2>(
            &on_signal_callbacks_[power_manager::kPowerSupplyPollSignal]));

    power_supply_training_condition_ =
        std::make_unique<PowerSupplyTrainingCondition>(mock_dbus_.get());
  }

  void InvokeSignal(const std::string& signal_name, dbus::Signal* signal) {
    ASSERT_TRUE(signal);
    auto callback_iter = on_signal_callbacks_.find(signal_name);
    ASSERT_NE(callback_iter, on_signal_callbacks_.end());
    callback_iter->second.Run(signal);
  }

  PowerSupplyTrainingCondition* power_supply_training_condition() const {
    DCHECK(power_supply_training_condition_);
    return power_supply_training_condition_.get();
  }

 private:
  scoped_refptr<StrictMock<dbus::MockBus>> mock_dbus_;

  scoped_refptr<StrictMock<dbus::MockObjectProxy>> dbus_object_proxy_;

  std::unique_ptr<PowerSupplyTrainingCondition>
      power_supply_training_condition_;

  // Currently, PowerSupply only connects to one signal, but may use more
  // in the future.
  std::unordered_map<std::string,
                     base::RepeatingCallback<void(dbus::Signal* signal)>>
      on_signal_callbacks_;
};

// Tests PowerSupply is initialized correctly and can handle unexpected
// empty proto messages.
TEST_F(PowerSupplyTrainingConditionTest, EmptySignal) {
  dbus::Signal signal(kPowerManagerInterface, kPowerSupplyPollSignal);

  // Initialized as false;
  EXPECT_FALSE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());

  // Invoke kPowerSupplyPollSignal without a valid proto message.
  InvokeSignal(kPowerSupplyPollSignal, &signal);
  EXPECT_FALSE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());

  // Invoke kPowerSupplyPollSignal with a valid empty proto message.
  WriteSerializedProtoToSignal("", &signal);
  InvokeSignal(kPowerSupplyPollSignal, &signal);
  EXPECT_FALSE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());
}

TEST_F(PowerSupplyTrainingConditionTest, PowerSupplySatisfied) {
  // Note: here we must create new signals rather than write to the old one,
  // because the WriteSerializedProtoToSignal is effectively "append", only the
  // first written string can be read by the DeviceStatusMonitor.

  // battery = 95, state = discharging, satisfied.
  dbus::Signal signal_1(kPowerManagerInterface, kPowerSupplyPollSignal);
  WriteSerializedProtoToSignal(
      GeneratePowerSupplyProto(
          95.0, power_manager::PowerSupplyProperties::DISCHARGING)
          .SerializeAsString(),
      &signal_1);
  InvokeSignal(kPowerSupplyPollSignal, &signal_1);
  EXPECT_TRUE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());

  // battery = 50, state = charging, satisfied.
  dbus::Signal signal_2(kPowerManagerInterface, kPowerSupplyPollSignal);
  WriteSerializedProtoToSignal(
      GeneratePowerSupplyProto(50.0,
                               power_manager::PowerSupplyProperties::CHARGING)
          .SerializeAsString(),
      &signal_2);
  InvokeSignal(kPowerSupplyPollSignal, &signal_2);
  EXPECT_TRUE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());

  // battery = 100, state = full, satisfied.
  dbus::Signal signal_3(kPowerManagerInterface, kPowerSupplyPollSignal);
  WriteSerializedProtoToSignal(
      GeneratePowerSupplyProto(100.0,
                               power_manager::PowerSupplyProperties::FULL)
          .SerializeAsString(),
      &signal_3);
  InvokeSignal(kPowerSupplyPollSignal, &signal_3);
  EXPECT_TRUE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());
}

TEST_F(PowerSupplyTrainingConditionTest, PowerSupplyNotSatisfied) {
  // battery = 80, state = discharging, unsatisfied.
  dbus::Signal signal(kPowerManagerInterface, kPowerSupplyPollSignal);
  WriteSerializedProtoToSignal(
      GeneratePowerSupplyProto(
          80.0, power_manager::PowerSupplyProperties::DISCHARGING)
          .SerializeAsString(),
      &signal);
  InvokeSignal(kPowerSupplyPollSignal, &signal);
  EXPECT_FALSE(
      power_supply_training_condition()->IsTrainingConditionSatisfied());
}

}  // namespace federated
