// Copyright 2017 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 "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"

#include <memory>
#include <utility>

#include "ash/public/cpp/ash_pref_names.h"
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_policy_controller.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/test_web_ui.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

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

namespace chromeos {
namespace settings {

namespace {

PrefService* GetPrefs() {
  return ProfileManager::GetActiveUserProfile()->GetPrefs();
}

}  // namespace

class TestPowerHandler : public PowerHandler {
 public:
  explicit TestPowerHandler(PrefService* prefs) : PowerHandler(prefs) {}

  // Pull WebUIMessageHandler::set_web_ui() into public so tests can call it.
  using PowerHandler::set_web_ui;
};

class PowerHandlerTest : public InProcessBrowserTest {
 protected:
  PowerHandlerTest() = default;
  ~PowerHandlerTest() override = default;

  // InProcessBrowserTest:
  void SetUpInProcessBrowserTestFixture() override {
    // Initialize user policy.
    ON_CALL(provider_, IsInitializationComplete(_)).WillByDefault(Return(true));
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_);
  }

  void SetUpOnMainThread() override {
    handler_ = std::make_unique<TestPowerHandler>(GetPrefs());
    test_api_ = std::make_unique<PowerHandler::TestAPI>(handler_.get());
    handler_->set_web_ui(&web_ui_);
    handler_->RegisterMessages();
    handler_->AllowJavascriptForTesting();
    base::RunLoop().RunUntilIdle();
  }

  void TearDownOnMainThread() override {
    test_api_.reset();
    handler_.reset();
  }

  // Returns a JSON representation of the contents of the last message sent to
  // WebUI about settings being changed.
  std::string GetLastSettingsChangedMessage() WARN_UNUSED_RESULT {
    for (auto it = web_ui_.call_data().rbegin();
         it != web_ui_.call_data().rend(); ++it) {
      const content::TestWebUI::CallData* data = it->get();
      std::string name;
      const base::DictionaryValue* dict = nullptr;
      if (data->function_name() != "cr.webUIListenerCallback" ||
          !data->arg1()->GetAsString(&name) ||
          name != PowerHandler::kPowerManagementSettingsChangedName) {
        continue;
      }
      if (!data->arg2()->GetAsDictionary(&dict)) {
        ADD_FAILURE() << "Failed to get dict from " << name << " message";
        continue;
      }
      std::string out;
      EXPECT_TRUE(base::JSONWriter::Write(*dict, &out));
      return out;
    }

    ADD_FAILURE() << PowerHandler::kPowerManagementSettingsChangedName
                  << " message was not sent";
    return std::string();
  }

  // Returns a string for the given settings that can be compared against the
  // output of GetLastSettingsChangedMessage().
  std::string CreateSettingsChangedString(
      PowerHandler::IdleBehavior idle_behavior,
      bool idle_controlled,
      PowerPolicyController::Action lid_closed_behavior,
      bool lid_closed_controlled,
      bool has_lid) {
    base::DictionaryValue dict;
    dict.SetInteger(PowerHandler::kIdleBehaviorKey,
                    static_cast<int>(idle_behavior));
    dict.SetBoolean(PowerHandler::kIdleControlledKey, idle_controlled);
    dict.SetInteger(PowerHandler::kLidClosedBehaviorKey, lid_closed_behavior);
    dict.SetBoolean(PowerHandler::kLidClosedControlledKey,
                    lid_closed_controlled);
    dict.SetBoolean(PowerHandler::kHasLidKey, has_lid);

    std::string out;
    EXPECT_TRUE(base::JSONWriter::Write(dict, &out));
    return out;
  }

  // Returns the user-set value of the integer pref identified by |name| or -1
  // if the pref is unset.
  int GetIntPref(const std::string& name) {
    if (!GetPrefs()->HasPrefPath(name))
      return -1;
    return GetPrefs()->GetInteger(name);
  }

  // Sets a policy update which will cause power pref managed change.
  void SetPolicyForPolicyKey(policy::PolicyMap* policy_map,
                             const std::string& policy_key,
                             std::unique_ptr<base::Value> value) {
    policy_map->Set(policy_key, policy::POLICY_LEVEL_MANDATORY,
                    policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
                    std::move(value), nullptr);
    provider_.UpdateChromePolicy(*policy_map);
    base::RunLoop().RunUntilIdle();
  }

  std::unique_ptr<TestPowerHandler> handler_;
  std::unique_ptr<TestPowerHandler::TestAPI> test_api_;

  content::TestWebUI web_ui_;

  policy::MockConfigurationPolicyProvider provider_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PowerHandlerTest);
};

// Verifies that settings are sent to WebUI when requested.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendInitialSettings) {
  test_api_->RequestPowerManagementSettings();
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
          false /* lid_closed_controlled */, true /* has_lid */),
      GetLastSettingsChangedMessage());
}

// Verifies that WebUI receives updated settings when the lid state changes.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForLidStateChanges) {
  chromeos::FakePowerManagerClient::Get()->SetLidState(
      PowerManagerClient::LidState::NOT_PRESENT, base::TimeTicks());
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
          false /* lid_closed_controlled */, false /* has_lid */),
      GetLastSettingsChangedMessage());

  chromeos::FakePowerManagerClient::Get()->SetLidState(
      PowerManagerClient::LidState::OPEN, base::TimeTicks());
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          false /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
          false /* lid_closed_controlled */, true /* has_lid */),
      GetLastSettingsChangedMessage());
}

// Verifies that when various prefs are controlled, the corresponding settings
// are reported as controlled to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendSettingsForControlledPrefs) {
  policy::PolicyMap policy_map;
  // Making an arbitrary delay pref managed should result in the idle setting
  // being reported as controlled.
  SetPolicyForPolicyKey(&policy_map, policy::key::kScreenDimDelayAC,
                        std::make_unique<base::Value>(10000));
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
          false /* lid_closed_controlled */, true /* has_lid */),
      GetLastSettingsChangedMessage());

  // Ditto for making the lid action pref managed.
  SetPolicyForPolicyKey(
      &policy_map, policy::key::kLidCloseAction,
      std::make_unique<base::Value>(PowerPolicyController::ACTION_SUSPEND));
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          true /* idle_controlled */, PowerPolicyController::ACTION_SUSPEND,
          true /* lid_closed_controlled */, true /* has_lid */),
      GetLastSettingsChangedMessage());
}

// Verifies that idle-related prefs are distilled into the proper WebUI
// settings.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendIdleSettingForPrefChanges) {
  // Set a do-nothing idle action and a nonzero screen-off delay.
  GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
                  base::Value(PowerPolicyController::ACTION_DO_NOTHING));
  GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(10000));
  EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_OFF,
                                        false /* idle_controlled */,
                                        PowerPolicyController::ACTION_SUSPEND,
                                        false /* lid_closed_controlled */,
                                        true /* has_lid */),
            GetLastSettingsChangedMessage());

  // Now set the delay to zero and check that the setting goes to "display on".
  GetPrefs()->Set(ash::prefs::kPowerAcScreenOffDelayMs, base::Value(0));
  EXPECT_EQ(CreateSettingsChangedString(PowerHandler::IdleBehavior::DISPLAY_ON,
                                        false /* idle_controlled */,
                                        PowerPolicyController::ACTION_SUSPEND,
                                        false /* lid_closed_controlled */,
                                        true /* has_lid */),
            GetLastSettingsChangedMessage());

  // Other idle actions should result in an "other" setting.
  GetPrefs()->Set(ash::prefs::kPowerAcIdleAction,
                  base::Value(PowerPolicyController::ACTION_STOP_SESSION));
  EXPECT_EQ(CreateSettingsChangedString(
                PowerHandler::IdleBehavior::OTHER, false /* idle_controlled */,
                PowerPolicyController::ACTION_SUSPEND,
                false /* lid_closed_controlled */, true /* has_lid */),
            GetLastSettingsChangedMessage());
}

// Verifies that the lid-closed pref's value is sent directly to WebUI.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SendLidSettingForPrefChanges) {
  GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
                  base::Value(PowerPolicyController::ACTION_SHUT_DOWN));
  EXPECT_EQ(
      CreateSettingsChangedString(
          PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
          false /* idle_controlled */, PowerPolicyController::ACTION_SHUT_DOWN,
          false /* lid_closed_controlled */, true /* has_lid */),
      GetLastSettingsChangedMessage());

  GetPrefs()->Set(ash::prefs::kPowerLidClosedAction,
                  base::Value(PowerPolicyController::ACTION_STOP_SESSION));
  EXPECT_EQ(CreateSettingsChangedString(
                PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP,
                false /* idle_controlled */,
                PowerPolicyController::ACTION_STOP_SESSION,
                false /* lid_closed_controlled */, true /* has_lid */),
            GetLastSettingsChangedMessage());
}

// Verifies that requests from WebUI to update the idle behavior update prefs
// appropriately.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SetIdleBehavior) {
  // Request the "Keep display on" setting and check that prefs are set
  // appropriately.
  test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
  EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
            GetIntPref(ash::prefs::kPowerAcIdleAction));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
  EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
            GetIntPref(ash::prefs::kPowerBatteryIdleAction));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
  EXPECT_EQ(0, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));

  // "Turn off display" should set the idle prefs but clear the screen
  // delays.
  test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF);
  EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
            GetIntPref(ash::prefs::kPowerAcIdleAction));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
  EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
            GetIntPref(ash::prefs::kPowerBatteryIdleAction));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));

  // Now switch to the "Keep display on" setting (to set the prefs again) and
  // check that the "Turn off display and sleep" setting clears all the prefs.
  test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_ON);
  test_api_->SetIdleBehavior(PowerHandler::IdleBehavior::DISPLAY_OFF_SLEEP);
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcIdleAction));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenDimDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenOffDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerAcScreenLockDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryIdleAction));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenDimDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenOffDelayMs));
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerBatteryScreenLockDelayMs));
}

// Verifies that requests from WebUI to change the lid behavior update the pref.
IN_PROC_BROWSER_TEST_F(PowerHandlerTest, SetLidBehavior) {
  // The "do nothing" setting should update the pref.
  test_api_->SetLidClosedBehavior(PowerPolicyController::ACTION_DO_NOTHING);
  EXPECT_EQ(PowerPolicyController::ACTION_DO_NOTHING,
            GetIntPref(ash::prefs::kPowerLidClosedAction));

  // Selecting the "suspend" setting should just clear the pref.
  test_api_->SetLidClosedBehavior(PowerPolicyController::ACTION_SUSPEND);
  EXPECT_EQ(-1, GetIntPref(ash::prefs::kPowerLidClosedAction));
}

}  // namespace settings
}  // namespace chromeos
