// Copyright 2014 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 "services/device/battery/battery_status_service.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "services/device/battery/battery_status_manager.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace device {

namespace {

class FakeBatteryManager : public BatteryStatusManager {
 public:
  explicit FakeBatteryManager(
      const BatteryStatusService::BatteryUpdateCallback& callback)
      : callback_(callback), start_invoked_count_(0), stop_invoked_count_(0) {}
  ~FakeBatteryManager() override {}

  // Methods from Battery Status Manager
  bool StartListeningBatteryChange() override {
    start_invoked_count_++;
    return true;
  }

  void StopListeningBatteryChange() override { stop_invoked_count_++; }

  void InvokeUpdateCallback(const mojom::BatteryStatus& status) {
    callback_.Run(status);
  }

  int start_invoked_count() const { return start_invoked_count_; }
  int stop_invoked_count() const { return stop_invoked_count_; }

 private:
  BatteryStatusService::BatteryUpdateCallback callback_;
  int start_invoked_count_;
  int stop_invoked_count_;

  DISALLOW_COPY_AND_ASSIGN(FakeBatteryManager);
};

}  // namespace

class BatteryStatusServiceTest : public testing::Test {
 public:
  BatteryStatusServiceTest()
      : battery_manager_(nullptr),
        callback1_invoked_count_(0),
        callback2_invoked_count_(0) {}
  ~BatteryStatusServiceTest() override {}

 protected:
  typedef BatteryStatusService::BatteryUpdateSubscription BatterySubscription;

  void SetUp() override {
    callback1_ = base::Bind(&BatteryStatusServiceTest::Callback1,
                            base::Unretained(this));
    callback2_ = base::Bind(&BatteryStatusServiceTest::Callback2,
                            base::Unretained(this));

    // We keep a raw pointer to the FakeBatteryManager, which we expect to
    // remain valid for the lifetime of the BatteryStatusService.
    auto battery_manager = std::make_unique<FakeBatteryManager>(
        battery_service_.GetUpdateCallbackForTesting());
    battery_manager_ = battery_manager.get();

    battery_service_.SetBatteryManagerForTesting(std::move(battery_manager));
  }

  void TearDown() override { base::RunLoop().RunUntilIdle(); }

  FakeBatteryManager* battery_manager() { return battery_manager_; }

  std::unique_ptr<BatterySubscription> AddCallback(
      const BatteryStatusService::BatteryUpdateCallback& callback) {
    return battery_service_.AddCallback(callback);
  }

  int callback1_invoked_count() const { return callback1_invoked_count_; }

  int callback2_invoked_count() const { return callback2_invoked_count_; }

  const mojom::BatteryStatus& battery_status() const { return battery_status_; }

  const BatteryStatusService::BatteryUpdateCallback& callback1() const {
    return callback1_;
  }

  const BatteryStatusService::BatteryUpdateCallback& callback2() const {
    return callback2_;
  }

 private:
  void Callback1(const mojom::BatteryStatus& status) {
    callback1_invoked_count_++;
    battery_status_ = status;
  }

  void Callback2(const mojom::BatteryStatus& status) {
    callback2_invoked_count_++;
    battery_status_ = status;
  }

  base::MessageLoop message_loop_;
  BatteryStatusService battery_service_;
  FakeBatteryManager* battery_manager_;
  BatteryStatusService::BatteryUpdateCallback callback1_;
  BatteryStatusService::BatteryUpdateCallback callback2_;
  int callback1_invoked_count_;
  int callback2_invoked_count_;
  mojom::BatteryStatus battery_status_;

  DISALLOW_COPY_AND_ASSIGN(BatteryStatusServiceTest);
};

TEST_F(BatteryStatusServiceTest, AddFirstCallback) {
  std::unique_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
  EXPECT_EQ(1, battery_manager()->start_invoked_count());
  EXPECT_EQ(0, battery_manager()->stop_invoked_count());
  subscription1.reset();
  EXPECT_EQ(1, battery_manager()->start_invoked_count());
  EXPECT_EQ(1, battery_manager()->stop_invoked_count());
}

TEST_F(BatteryStatusServiceTest, AddCallbackAfterUpdate) {
  std::unique_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
  mojom::BatteryStatus status;
  battery_manager()->InvokeUpdateCallback(status);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback1_invoked_count());
  EXPECT_EQ(0, callback2_invoked_count());

  std::unique_ptr<BatterySubscription> subscription2 = AddCallback(callback2());
  EXPECT_EQ(1, callback1_invoked_count());
  EXPECT_EQ(1, callback2_invoked_count());
}

TEST_F(BatteryStatusServiceTest, TwoCallbacksUpdate) {
  std::unique_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
  std::unique_ptr<BatterySubscription> subscription2 = AddCallback(callback2());

  mojom::BatteryStatus status;
  status.charging = true;
  status.charging_time = 100;
  status.discharging_time = 200;
  status.level = 0.5;
  battery_manager()->InvokeUpdateCallback(status);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, callback1_invoked_count());
  EXPECT_EQ(1, callback2_invoked_count());
  EXPECT_EQ(status.charging, battery_status().charging);
  EXPECT_EQ(status.charging_time, battery_status().charging_time);
  EXPECT_EQ(status.discharging_time, battery_status().discharging_time);
  EXPECT_EQ(status.level, battery_status().level);
}

TEST_F(BatteryStatusServiceTest, RemoveOneCallback) {
  std::unique_ptr<BatterySubscription> subscription1 = AddCallback(callback1());
  std::unique_ptr<BatterySubscription> subscription2 = AddCallback(callback2());

  mojom::BatteryStatus status;
  battery_manager()->InvokeUpdateCallback(status);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback1_invoked_count());
  EXPECT_EQ(1, callback2_invoked_count());

  subscription1.reset();
  battery_manager()->InvokeUpdateCallback(status);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback1_invoked_count());
  EXPECT_EQ(2, callback2_invoked_count());
}

}  // namespace device
