// Copyright 2017 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 <unordered_set>

#include <base/strings/string_util.h>
#include <components/policy/core/common/registry_dict.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "authpolicy/policy/device_policy_encoder.h"
#include "authpolicy/policy/policy_encoder_test_base.h"
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/policy_constants.h"

namespace em = enterprise_management;

namespace policy {

namespace {

// Converts a repeated string field to a vector.
std::vector<std::string> ToVector(
    const google::protobuf::RepeatedPtrField<std::string>& repeated_field) {
  return std::vector<std::string>(repeated_field.begin(), repeated_field.end());
}

// Converts a repeated int field to a vector.
std::vector<int> ToVector(
    const google::protobuf::RepeatedField<int>& repeated_field) {
  return std::vector<int>(repeated_field.begin(), repeated_field.end());
}

}  // namespace

// Checks whether all device policies are properly encoded from RegistryDict
// into em::ChromeDeviceSettingsProto. Makes sure no device policy is missing.
class DevicePolicyEncoderTest
    : public PolicyEncoderTestBase<em::ChromeDeviceSettingsProto> {
 public:
  DevicePolicyEncoderTest() {}
  ~DevicePolicyEncoderTest() override {}

 protected:
  void EncodeDict(em::ChromeDeviceSettingsProto* policy,
                  const RegistryDict* dict) override {
    DevicePolicyEncoder encoder(dict);
    *policy = em::ChromeDeviceSettingsProto();
    encoder.EncodePolicy(policy);
  }

  void MarkHandled(const char* key) override {
    handled_policy_keys_.insert(key);
  }

  // Returns a vector of all policy keys that were not encoded or otherwise
  // marked handled (e.g. unsupported policies).
  std::vector<std::string> GetUnhandledPolicyKeys() const {
    std::vector<std::string> unhandled_policy_keys;
    for (const char** key = kDevicePolicyKeys; *key; ++key) {
      if (handled_policy_keys_.find(*key) == handled_policy_keys_.end())
        unhandled_policy_keys.push_back(*key);
    }
    return unhandled_policy_keys;
  }

 private:
  // Keeps track of handled device policies. Used to detect device policies that
  // device_policy_encoder forgets to encode.
  std::unordered_set<std::string> handled_policy_keys_;

  DISALLOW_COPY_AND_ASSIGN(DevicePolicyEncoderTest);
};

TEST_F(DevicePolicyEncoderTest, TestEncoding) {
  // Note that kStringList can't be constexpr, so we put them all here.
  const bool kBool = true;
  const int kInt = 123;
  const std::string kString = "val1";
  const std::vector<std::string> kStringList = {"val1", "val2", "val3"};

  em::ChromeDeviceSettingsProto policy;

  //
  // Login policies.
  //

  EncodeBoolean(&policy, key::kDeviceGuestModeEnabled, kBool);
  EXPECT_EQ(kBool, policy.guest_mode_enabled().guest_mode_enabled());

  EncodeBoolean(&policy, key::kDeviceRebootOnShutdown, kBool);
  EXPECT_EQ(kBool, policy.reboot_on_shutdown().reboot_on_shutdown());

  EncodeBoolean(&policy, key::kDeviceShowUserNamesOnSignin, kBool);
  EXPECT_EQ(kBool, policy.show_user_names().show_user_names());

  EncodeBoolean(&policy, key::kDeviceAllowNewUsers, kBool);
  EXPECT_EQ(kBool, policy.allow_new_users().allow_new_users());

  EncodeStringList(&policy, key::kDeviceUserWhitelist, kStringList);
  EXPECT_EQ(kStringList, ToVector(policy.user_whitelist().user_whitelist()));

  EncodeBoolean(&policy, key::kDeviceEphemeralUsersEnabled, kBool);
  EXPECT_EQ(kBool, policy.ephemeral_users_enabled().ephemeral_users_enabled());

  // Unsupported, see device_policy_encoder.cc for explanation, simply mark
  // handled.
  MarkHandled(key::kDeviceLocalAccounts);
  EncodeString(&policy, key::kDeviceLocalAccountAutoLoginId, kString);
  EXPECT_EQ(kString, policy.device_local_accounts().auto_login_id());
  EncodeInteger(&policy, key::kDeviceLocalAccountAutoLoginDelay, kInt);
  EXPECT_EQ(kInt, policy.device_local_accounts().auto_login_delay());
  EncodeBoolean(
      &policy, key::kDeviceLocalAccountAutoLoginBailoutEnabled, kBool);
  EXPECT_EQ(kBool, policy.device_local_accounts().enable_auto_login_bailout());
  EncodeBoolean(
      &policy, key::kDeviceLocalAccountPromptForNetworkWhenOffline, kBool);
  EXPECT_EQ(kBool,
            policy.device_local_accounts().prompt_for_network_when_offline());

  EncodeBoolean(&policy, key::kSupervisedUsersEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.supervised_users_settings().supervised_users_enabled());

  EncodeBoolean(&policy, key::kDeviceTransferSAMLCookies, kBool);
  EXPECT_EQ(kBool, policy.saml_settings().transfer_saml_cookies());

  // The encoder of this policy converts ints to LoginBehavior enums.
  EncodeInteger(&policy,
                key::kLoginAuthenticationBehavior,
                em::LoginAuthenticationBehaviorProto::SAML_INTERSTITIAL);
  EXPECT_EQ(
      em::LoginAuthenticationBehaviorProto::SAML_INTERSTITIAL,
      policy.login_authentication_behavior().login_authentication_behavior());

  EncodeBoolean(&policy, key::kDeviceAllowBluetooth, kBool);
  EXPECT_EQ(kBool, policy.allow_bluetooth().allow_bluetooth());
  EncodeStringList(&policy, key::kLoginVideoCaptureAllowedUrls, kStringList);
  EXPECT_EQ(kStringList,
            ToVector(policy.login_video_capture_allowed_urls().urls()));
  EncodeStringList(&policy, key::kDeviceLoginScreenAppInstallList, kStringList);
  EXPECT_EQ(kStringList,
            ToVector(policy.device_login_screen_app_install_list()
                         .device_login_screen_app_install_list()));
  EncodeStringList(&policy, key::kDeviceLoginScreenLocales, kStringList);
  EXPECT_EQ(kStringList,
            ToVector(policy.login_screen_locales().login_screen_locales()));
  EncodeStringList(&policy, key::kDeviceLoginScreenInputMethods, kStringList);
  EXPECT_EQ(
      kStringList,
      ToVector(
          policy.login_screen_input_methods().login_screen_input_methods()));

  //
  // Network policies.
  //

  EncodeBoolean(&policy, key::kDeviceDataRoamingEnabled, kBool);
  EXPECT_EQ(kBool, policy.data_roaming_enabled().data_roaming_enabled());

  // The encoder of this policy converts a json string to separate values.
  EncodeString(&policy,
               key::kNetworkThrottlingEnabled,
               "{\"enabled\":true,"
               " \"upload_rate_kbits\":128,"
               " \"download_rate_kbits\":256}");
  EXPECT_EQ(true, policy.network_throttling().enabled());
  EXPECT_EQ(128, policy.network_throttling().upload_rate_kbits());
  EXPECT_EQ(256, policy.network_throttling().download_rate_kbits());

  EncodeString(&policy, key::kDeviceOpenNetworkConfiguration, kString);
  EXPECT_EQ(kString,
            policy.open_network_configuration().open_network_configuration());

  //
  // Reporting policies.
  //

  EncodeBoolean(&policy, key::kReportDeviceVersionInfo, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_version_info());
  EncodeBoolean(&policy, key::kReportDeviceActivityTimes, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_activity_times());
  EncodeBoolean(&policy, key::kReportDeviceBootMode, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_boot_mode());
  EncodeBoolean(&policy, key::kReportDeviceLocation, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_location());
  EncodeBoolean(&policy, key::kReportDeviceNetworkInterfaces, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_network_interfaces());
  EncodeBoolean(&policy, key::kReportDeviceUsers, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_users());
  EncodeBoolean(&policy, key::kReportDeviceHardwareStatus, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_hardware_status());
  EncodeBoolean(&policy, key::kReportDeviceSessionStatus, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().report_session_status());
  EncodeBoolean(&policy, key::kReportUploadFrequency, kBool);
  EXPECT_EQ(kBool, policy.device_reporting().device_status_frequency());

  EncodeBoolean(&policy, key::kHeartbeatEnabled, kBool);
  EXPECT_EQ(kBool, policy.device_heartbeat_settings().heartbeat_enabled());
  EncodeInteger(&policy, key::kHeartbeatFrequency, kInt);
  EXPECT_EQ(kInt, policy.device_heartbeat_settings().heartbeat_frequency());

  EncodeBoolean(&policy, key::kLogUploadEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.device_log_upload_settings().system_log_upload_enabled());

  //
  // Auto update policies.
  //

  EncodeString(&policy, key::kChromeOsReleaseChannel, kString);
  EXPECT_EQ(kString, policy.release_channel().release_channel());
  EncodeBoolean(&policy, key::kChromeOsReleaseChannelDelegated, kBool);
  EXPECT_EQ(kBool, policy.release_channel().release_channel_delegated());

  EncodeBoolean(&policy, key::kDeviceAutoUpdateDisabled, kBool);
  EXPECT_EQ(kBool, policy.auto_update_settings().update_disabled());
  EncodeString(&policy, key::kDeviceTargetVersionPrefix, kString);
  EXPECT_EQ(kString, policy.auto_update_settings().target_version_prefix());

  EncodeInteger(&policy, key::kDeviceUpdateScatterFactor, kInt);
  EXPECT_EQ(kInt, policy.auto_update_settings().scatter_factor_in_seconds());
  // The encoder of this policy converts connection type strings to enums.
  std::vector<std::string> str_types;
  std::vector<int> enum_types;
  for (size_t n = 0; n < kConnectionTypesSize; ++n) {
    str_types.push_back(kConnectionTypes[n].first);
    enum_types.push_back(kConnectionTypes[n].second);
  }
  EncodeStringList(
      &policy, key::kDeviceUpdateAllowedConnectionTypes, str_types);
  EXPECT_EQ(enum_types,
            ToVector(policy.auto_update_settings().allowed_connection_types()));
  EncodeBoolean(&policy, key::kDeviceUpdateHttpDownloadsEnabled, kBool);
  EXPECT_EQ(kBool, policy.auto_update_settings().http_downloads_enabled());
  EncodeBoolean(&policy, key::kRebootAfterUpdate, kBool);
  EXPECT_EQ(kBool, policy.auto_update_settings().reboot_after_update());
  EncodeBoolean(&policy, key::kDeviceAutoUpdateP2PEnabled, kBool);
  EXPECT_EQ(kBool, policy.auto_update_settings().p2p_enabled());

  EncodeBoolean(&policy, key::kAllowKioskAppControlChromeVersion, kBool);
  EXPECT_EQ(kBool,
            policy.allow_kiosk_app_control_chrome_version()
                .allow_kiosk_app_control_chrome_version());

  //
  // Accessibility policies.
  //

  EncodeBoolean(
      &policy, key::kDeviceLoginScreenDefaultLargeCursorEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.accessibility_settings()
                .login_screen_default_large_cursor_enabled());
  EncodeBoolean(
      &policy, key::kDeviceLoginScreenDefaultSpokenFeedbackEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.accessibility_settings()
                .login_screen_default_spoken_feedback_enabled());
  EncodeBoolean(
      &policy, key::kDeviceLoginScreenDefaultHighContrastEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.accessibility_settings()
                .login_screen_default_high_contrast_enabled());
  // The encoder of this policy converts ints to ScreenMagnifierType enums.
  EncodeInteger(&policy,
                key::kDeviceLoginScreenDefaultScreenMagnifierType,
                em::AccessibilitySettingsProto::SCREEN_MAGNIFIER_TYPE_FULL);
  EXPECT_EQ(em::AccessibilitySettingsProto::SCREEN_MAGNIFIER_TYPE_FULL,
            policy.accessibility_settings()
                .login_screen_default_screen_magnifier_type());
  EncodeBoolean(
      &policy, key::kDeviceLoginScreenDefaultVirtualKeyboardEnabled, kBool);
  EXPECT_EQ(kBool,
            policy.accessibility_settings()
                .login_screen_default_virtual_keyboard_enabled());

  //
  // Generic policies.
  //

  EncodeInteger(&policy, key::kDevicePolicyRefreshRate, kInt);
  EXPECT_EQ(kInt,
            policy.device_policy_refresh_rate().device_policy_refresh_rate());

  EncodeBoolean(&policy, key::kDeviceMetricsReportingEnabled, kBool);
  EXPECT_EQ(kBool, policy.metrics_enabled().metrics_enabled());

  EncodeString(&policy, key::kSystemTimezone, kString);
  EXPECT_EQ(kString, policy.system_timezone().timezone());
  // The encoder of this policy converts ints to AutomaticTimezoneDetectionType
  // enums.
  EncodeInteger(&policy,
                key::kSystemTimezoneAutomaticDetection,
                em::SystemTimezoneProto::IP_ONLY);
  EXPECT_EQ(em::SystemTimezoneProto::IP_ONLY,
            policy.system_timezone().timezone_detection_type());

  EncodeBoolean(&policy, key::kSystemUse24HourClock, kBool);
  EXPECT_EQ(kBool, policy.use_24hour_clock().use_24hour_clock());

  EncodeBoolean(
      &policy, key::kDeviceAllowRedeemChromeOsRegistrationOffers, kBool);
  EXPECT_EQ(kBool, policy.allow_redeem_offers().allow_redeem_offers());

  EncodeInteger(&policy, key::kUptimeLimit, kInt);
  EXPECT_EQ(kInt, policy.uptime_limit().uptime_limit());

  EncodeStringList(&policy, key::kDeviceStartUpFlags, kStringList);
  EXPECT_EQ(kStringList, ToVector(policy.start_up_flags().flags()));

  EncodeString(&policy, key::kDeviceVariationsRestrictParameter, kString);
  EXPECT_EQ(kString, policy.variations_parameter().parameter());

  EncodeBoolean(&policy, key::kAttestationEnabledForDevice, kBool);
  EXPECT_EQ(kBool, policy.attestation_settings().attestation_enabled());
  EncodeBoolean(&policy, key::kAttestationForContentProtectionEnabled, kBool);
  EXPECT_EQ(kBool, policy.attestation_settings().content_protection_enabled());

  EncodeString(&policy, key::kDeviceLoginScreenPowerManagement, kString);
  EXPECT_EQ(
      kString,
      policy.login_screen_power_management().login_screen_power_management());

  EncodeBoolean(&policy, key::kDeviceBlockDevmode, kBool);
  EXPECT_EQ(kBool, policy.system_settings().block_devmode());

  EncodeInteger(&policy, key::kExtensionCacheSize, kInt);
  EXPECT_EQ(kInt, policy.extension_cache_size().extension_cache_size());

  EncodeString(&policy, key::kDeviceLoginScreenDomainAutoComplete, kString);
  EXPECT_EQ(kString,
            policy.login_screen_domain_auto_complete()
                .login_screen_domain_auto_complete());

  // The encoder of this policy converts ints to Rotation enums.
  EncodeInteger(&policy,
                key::kDisplayRotationDefault,
                em::DisplayRotationDefaultProto::ROTATE_180);
  EXPECT_EQ(em::DisplayRotationDefaultProto::ROTATE_180,
            policy.display_rotation_default().display_rotation_default());

  // The encoder of this policy converts a json string to separate values.
  EncodeStringList(&policy,
                   key::kUsbDetachableWhitelist,
                   {"{\"vendor_id\":123, \"product_id\":234}",
                    "{\"vendor_id\":345, \"product_id\":456}"});
  const auto& whitelist_proto = policy.usb_detachable_whitelist();
  EXPECT_EQ(123, whitelist_proto.id().Get(0).vendor_id());
  EXPECT_EQ(234, whitelist_proto.id().Get(0).product_id());
  EXPECT_EQ(345, whitelist_proto.id().Get(1).vendor_id());
  EXPECT_EQ(456, whitelist_proto.id().Get(1).product_id());

  EncodeBoolean(&policy, key::kDeviceQuirksDownloadEnabled, kBool);
  EXPECT_EQ(kBool, policy.quirks_download_enabled().quirks_download_enabled());

  EncodeString(&policy, key::kDeviceWallpaperImage, kString);
  EXPECT_EQ(kString, policy.device_wallpaper_image().device_wallpaper_image());

  //
  // Check whether all device policies have been handled.
  //

  std::vector<std::string> unhandled_policy_keys = GetUnhandledPolicyKeys();
  EXPECT_TRUE(unhandled_policy_keys.empty())
      << "Unhandled policy detected.\n"
      << "Please handle the following policies in "
      << "device_policy_encoder.cc and device_policy_encoder_unittest.cc:\n"
      << "  " << base::JoinString(unhandled_policy_keys, "\n  ");
}

}  // namespace policy
