// Copyright 2013 The Flutter 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 "flutter/shell/platform/windows/settings_plugin.h"

#include "flutter/shell/platform/windows/task_runner.h"
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

namespace {

class MockSettingsPlugin : public SettingsPlugin {
 public:
  explicit MockSettingsPlugin(BinaryMessenger* messenger,
                              TaskRunner* task_runner)
      : SettingsPlugin(messenger, task_runner) {}

  virtual ~MockSettingsPlugin() = default;

  // |SettingsPlugin|
  MOCK_METHOD0(GetAlwaysUse24HourFormat, bool());
  MOCK_METHOD0(GetTextScaleFactor, float());
  MOCK_METHOD0(GetPreferredBrightness, PlatformBrightness());

  MOCK_METHOD0(WatchPreferredBrightnessChanged, void());
  MOCK_METHOD0(WatchTextScaleFactorChanged, void());
};

}  // namespace

TEST(SettingsPluginTest, SendSettingsSendsMessage) {
  bool message_is_sent = false;
  TestBinaryMessenger messenger(
      [&message_is_sent](const std::string& channel, const uint8_t* message,
                         size_t message_size,
                         BinaryReply reply) { message_is_sent = true; });
  ::testing::NiceMock<MockSettingsPlugin> settings_plugin(&messenger, nullptr);

  settings_plugin.SendSettings();

  EXPECT_TRUE(message_is_sent);
}

TEST(SettingsPluginTest, SendSettingsGetsSettings) {
  TestBinaryMessenger messenger([](const std::string& channel,
                                   const uint8_t* message, size_t message_size,
                                   BinaryReply reply) {});
  ::testing::NiceMock<MockSettingsPlugin> settings_plugin(&messenger, nullptr);

  EXPECT_CALL(settings_plugin, GetAlwaysUse24HourFormat).Times(1);
  EXPECT_CALL(settings_plugin, GetTextScaleFactor).Times(1);
  EXPECT_CALL(settings_plugin, GetPreferredBrightness).Times(1);

  settings_plugin.SendSettings();
}

TEST(SettingsPluginTest, StartWatchingStartsWatchingChanges) {
  TestBinaryMessenger messenger([](const std::string& channel,
                                   const uint8_t* message, size_t message_size,
                                   BinaryReply reply) {});
  ::testing::NiceMock<MockSettingsPlugin> settings_plugin(&messenger, nullptr);

  EXPECT_CALL(settings_plugin, WatchPreferredBrightnessChanged).Times(1);
  EXPECT_CALL(settings_plugin, WatchTextScaleFactorChanged).Times(1);

  settings_plugin.StartWatching();
}

}  // namespace testing
}  // namespace flutter
