// Copyright 2018 The Chromium 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 <limits>

#include "base/bind.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "extensions/browser/api/system_power_source/system_power_source_api.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/browser/api_unittest.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/event_router_factory.h"
#include "extensions/common/api/system_power_source.h"
#include "extensions/common/extension_builder.h"

using extensions::api::system_power_source::PowerSourceInfo;
using extensions::api_test_utils::RunFunctionAndReturnSingleResult;
namespace power_source_api = extensions::api::system_power_source;

namespace extensions {

namespace {

class SystemPowerSourceApiUnitTest : public ApiUnitTest {
 public:
  SystemPowerSourceApiUnitTest() {
    auto power_manager_client =
        std::make_unique<chromeos::FakePowerManagerClient>();
    power_manager_client_ = power_manager_client.get();

    chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
        std::move(power_manager_client));

    chromeos::DBusThreadManager::Initialize();
  }

  ~SystemPowerSourceApiUnitTest() override {
    chromeos::DBusThreadManager::Shutdown();
  }

  std::unique_ptr<base::Value> RunGetPowerSourceInfoFunction() {
    scoped_refptr<SystemPowerSourceGetPowerSourceInfoFunction>
        get_power_source_info_function(
            new SystemPowerSourceGetPowerSourceInfoFunction());

    get_power_source_info_function->set_extension(extension());
    get_power_source_info_function->set_has_callback(true);

    return RunFunctionAndReturnSingleResult(
        get_power_source_info_function.get(), "[]", browser_context());
  }

  std::unique_ptr<base::Value> RunRequestStatusUpdateFunction() {
    scoped_refptr<SystemPowerSourceRequestStatusUpdateFunction>
        request_status_update_function(
            new SystemPowerSourceRequestStatusUpdateFunction());

    request_status_update_function->set_extension(extension());

    return RunFunctionAndReturnSingleResult(
        request_status_update_function.get(), "[]", browser_context());
  }

  chromeos::FakePowerManagerClient* power_manager_client_;

  DISALLOW_COPY_AND_ASSIGN(SystemPowerSourceApiUnitTest);
};

class TestEventRouter : public EventRouter {
 public:
  explicit TestEventRouter(content::BrowserContext* context)
      : EventRouter(context, nullptr) {}
  ~TestEventRouter() override = default;

  void BroadcastEvent(std::unique_ptr<Event> event) override {
    if (event->event_name !=
        api::system_power_source::OnPowerChanged::kEventName) {
      return;
    }
    ASSERT_TRUE(event->event_args);
    ASSERT_EQ(1u, event->event_args->GetList().size());
    power_source_info_.emplace_back(event->event_args->GetList()[0].Clone());
  }

  const std::vector<base::Value>& power_source_info() const {
    return power_source_info_;
  }

  void clear_power_source_info() { power_source_info_.clear(); }

 private:
  std::vector<base::Value> power_source_info_;

  DISALLOW_COPY_AND_ASSIGN(TestEventRouter);
};

std::unique_ptr<KeyedService> TestEventRouterFactoryFunction(
    content::BrowserContext* context) {
  return std::make_unique<TestEventRouter>(context);
}

power_manager::PowerSupplyProperties MakePowerSupplyProperties(
    const base::Optional<std::string>& external_power_source_id,
    const std::vector<power_manager::PowerSupplyProperties_PowerSource>&
        power_sources) {
  power_manager::PowerSupplyProperties props;
  if (external_power_source_id)
    props.set_external_power_source_id(*external_power_source_id);

  for (const auto& power_source : power_sources)
    *props.add_available_external_power_source() = power_source;

  return props;
}

power_manager::PowerSupplyProperties_PowerSource MakePowerSource(
    const std::string& id,
    power_manager::PowerSupplyProperties_PowerSource_Type type,
    double max_power) {
  power_manager::PowerSupplyProperties_PowerSource power_source;
  power_source.set_id(id);
  power_source.set_type(type);
  power_source.set_max_power(max_power);
  return power_source;
}

}  // namespace

// Barrel jack connected
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceAc) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "AC",
      {MakePowerSource(
          "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
          0)}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", true)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

// USB-C PD charger connected
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceUsb) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "CROS_USB_PD_CHARGER0",
      {{MakePowerSource(
          "CROS_USB_PD_CHARGER0",
          power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, 60)}}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 60.0)
                      .Set("active", true)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

// Barrel Jack + USB-C PD charger connected; Barrel Jack active
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceAcActiveAndUsbInactive) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "AC",
      {{MakePowerSource(
            "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
            0),
        MakePowerSource(
            "CROS_USB_PD_CHARGER0",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C,
            60)}}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", true)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 60.0)
                      .Set("active", false)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

// Barrel Jack + USB-C PD charger connected; USB-C charger active
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceAcInactiveAndUsbActive) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "CROS_USB_PD_CHARGER0",
      {{MakePowerSource(
            "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
            0),
        MakePowerSource(
            "CROS_USB_PD_CHARGER0",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C,
            60)}}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 60.0)
                      .Set("active", true)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

// Barrel Jack + USB-C PD charger connected; neither active
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceNoneActive) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      base::nullopt,
      {{MakePowerSource(
            "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
            0),
        MakePowerSource(
            "CROS_USB_PD_CHARGER0",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C,
            60)}}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 60.0)
                      .Set("active", false)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

// Connected USB chargers with fractional max power gets rounded down to
// two significant digits (for privacy reasons, to reduce the risk of
// finger-printing).  Chargers with a max power that is not a normal value
// larger than zero are reported as not having a max power value.
TEST_F(SystemPowerSourceApiUnitTest, GetPowerSourceRounding) {
  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "CROS_USB_PD_CHARGER0",
      {{MakePowerSource(
            "CROS_USB_PD_CHARGER0",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, 111.0),
        MakePowerSource(
            "CROS_USB_PD_CHARGER1",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, 11.1),
        MakePowerSource(
            "CROS_USB_PD_CHARGER2",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, 1.11),
        MakePowerSource(
            "CROS_USB_PD_CHARGER3",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, 0.111),
        MakePowerSource(
            "CROS_USB_PD_CHARGER4",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C, -1),
        MakePowerSource(
            "CROS_USB_PD_CHARGER5",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C,
            std::nan("")),
        MakePowerSource(
            "CROS_USB_PD_CHARGER6",
            power_manager::PowerSupplyProperties_PowerSource_Type_USB_C,
            std::numeric_limits<double>::infinity())}}));

  std::unique_ptr<base::Value> result = RunGetPowerSourceInfoFunction();
  ASSERT_TRUE(result);

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 110.0)
                      .Set("active", true)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 11.0)
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 1.1)
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("maxPower", 0.11)
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("active", false)
                      .Build())
          .Append(DictionaryBuilder()
                      .Set("type", "usb")
                      .Set("active", false)
                      .Build())
          .Build();

  EXPECT_EQ(*expected_result, *result);
}

TEST_F(SystemPowerSourceApiUnitTest, OnPowerChangedEvent) {
  TestEventRouter* event_router = static_cast<TestEventRouter*>(
      EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
          browser_context(),
          base::BindRepeating(&TestEventRouterFactoryFunction)));
  SystemPowerSourceAPI system_power_source_api(browser_context());

  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "AC",
      {MakePowerSource(
          "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
          0)}));

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", true)
                      .Build())
          .Build();

  ASSERT_EQ(1U, event_router->power_source_info().size());
  EXPECT_EQ(*expected_result, event_router->power_source_info()[0]);
}

TEST_F(SystemPowerSourceApiUnitTest, RequestStatusUpdate) {
  TestEventRouter* event_router = static_cast<TestEventRouter*>(
      EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
          browser_context(),
          base::BindRepeating(&TestEventRouterFactoryFunction)));
  SystemPowerSourceAPI system_power_source_api(browser_context());

  power_manager_client_->UpdatePowerProperties(MakePowerSupplyProperties(
      "AC",
      {MakePowerSource(
          "AC", power_manager::PowerSupplyProperties_PowerSource_Type_MAINS,
          0)}));

  event_router->clear_power_source_info();

  RunRequestStatusUpdateFunction();
  base::RunLoop().RunUntilIdle();

  std::unique_ptr<base::Value> expected_result =
      ListBuilder()
          .Append(DictionaryBuilder()
                      .Set("type", "mains")
                      .Set("active", true)
                      .Build())
          .Build();

  ASSERT_EQ(1U, event_router->power_source_info().size());
  EXPECT_EQ(*expected_result, event_router->power_source_info()[0]);
}

}  // namespace extensions
