// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/policy/developer_tools_policy_handler.h"

#include <optional>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/policy/extension_developer_mode_policy_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/policy/core/browser/policy_error_map.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_value_map.h"
#include "components/strings/grit/components_strings.h"

namespace policy {

namespace {

using Availability = DeveloperToolsPolicyHandler::Availability;

// The result of checking a policy value.
enum class PolicyCheckResult {
  // The policy is not set.
  kNotSet,
  // The policy is set to an invalid value.
  kInvalid,
  // The policy is set to a valid value.
  kValid
};

#if BUILDFLAG(IS_ANDROID)
// key::kDeveloperToolsDisabled has been deprecated and has never been supported
// on Android.
std::optional<Availability> GetValueFromDeveloperToolsDisabledPolicy(
    const PolicyMap& policies) {
  return std::nullopt;
}
#else
// Checks the value of the DeveloperToolsDisabled policy. |errors| may be
// nullptr.
PolicyCheckResult CheckDeveloperToolsDisabled(
    const base::Value* developer_tools_disabled,
    policy::PolicyErrorMap* errors) {
  if (!developer_tools_disabled)
    return PolicyCheckResult::kNotSet;

  if (!developer_tools_disabled->is_bool()) {
    if (errors) {
      errors->AddError(key::kDeveloperToolsDisabled, IDS_POLICY_TYPE_ERROR,
                       base::Value::GetTypeName(base::Value::Type::BOOLEAN));
    }
    return PolicyCheckResult::kInvalid;
  }

  return PolicyCheckResult::kValid;
}

// Returns the target value of the |kDevToolsAvailability| pref derived only
// from the legacy DeveloperToolsDisabled policy. If this policy is not set or
// does not have a valid value, returns |nullopt|.
std::optional<Availability> GetValueFromDeveloperToolsDisabledPolicy(
    const PolicyMap& policies) {
  const base::Value* developer_tools_disabled = policies.GetValue(
      key::kDeveloperToolsDisabled, base::Value::Type::BOOLEAN);

  if (CheckDeveloperToolsDisabled(developer_tools_disabled,
                                  nullptr /*error*/) !=
      PolicyCheckResult::kValid) {
    return std::nullopt;
  }

  return developer_tools_disabled->GetBool() ? Availability::kDisallowed
                                             : Availability::kAllowed;
}
#endif  // BUILDFLAG(IS_ANDROID)

// Returns true if |value| is within the valid range of the
// DeveloperToolsAvailability enum policy.
bool IsValidDeveloperToolsAvailabilityValue(int value) {
  return value >= 0 && value <= static_cast<int>(Availability::kMaxValue);
}

// Checks the value of the DeveloperToolsAvailability policy. |errors| may be
// nullptr.
PolicyCheckResult CheckDeveloperToolsAvailability(
    const base::Value* developer_tools_availability,
    policy::PolicyErrorMap* errors) {
  if (!developer_tools_availability)
    return PolicyCheckResult::kNotSet;

  if (!developer_tools_availability->is_int()) {
    if (errors) {
      errors->AddError(key::kDeveloperToolsAvailability, IDS_POLICY_TYPE_ERROR,
                       base::Value::GetTypeName(base::Value::Type::INTEGER));
    }
    return PolicyCheckResult::kInvalid;
  }

  const int value = developer_tools_availability->GetInt();
  if (!IsValidDeveloperToolsAvailabilityValue(value)) {
    if (errors) {
      errors->AddError(key::kDeveloperToolsAvailability,
                       IDS_POLICY_OUT_OF_RANGE_ERROR,
                       base::NumberToString(value));
    }
    return PolicyCheckResult::kInvalid;
  }
  return PolicyCheckResult::kValid;
}

// Returns the target value of the |kDevToolsAvailability| pref derived only
// from the DeveloperToolsAvailability policy. If this policy is not set or does
// not have a valid value, returns |nullopt|.
std::optional<Availability> GetValueFromDeveloperToolsAvailabilityPolicy(
    const PolicyMap& policies) {
  // It is safe to use `GetValueUnsafe()` because type checking is performed
  // before the value is used.
  const base::Value* developer_tools_availability =
      policies.GetValueUnsafe(key::kDeveloperToolsAvailability);

  if (CheckDeveloperToolsAvailability(developer_tools_availability,
                                      nullptr /*error*/) !=
      PolicyCheckResult::kValid) {
    return std::nullopt;
  }

  return static_cast<Availability>(developer_tools_availability->GetInt());
}

// Returns the target value of the |kDevToolsAvailability| pref, derived from
// both the DeveloperToolsDisabled policy and the
// DeveloperToolsAvailability policy. If both policies are set,
// DeveloperToolsAvailability wins.
std::optional<Availability> GetValueFromBothPolicies(
    const PolicyMap& policies) {
  const std::optional<Availability> developer_tools_availability =
      GetValueFromDeveloperToolsAvailabilityPolicy(policies);

  if (developer_tools_availability.has_value()) {
    // DeveloperToolsAvailability overrides DeveloperToolsDisabled policy.
    return developer_tools_availability;
  }

  return GetValueFromDeveloperToolsDisabledPolicy(policies);
}

// Returns the current policy-set developer tools availability according to
// the values in |pref_service|. If no policy mandating developer tools
// availability is set, the default will be
// |Availability::kDisallowedForForceInstalledExtensions|.
Availability GetDevToolsAvailability(const PrefService* pref_sevice) {
  int value = pref_sevice->GetInteger(prefs::kDevToolsAvailability);
  if (!IsValidDeveloperToolsAvailabilityValue(value)) {
    // This should never happen, because the |kDevToolsAvailability| pref is
    // only set by DeveloperToolsPolicyHandler which validates the value range.
    // If it is not set, it will have its default value which is also valid, see
    // |RegisterProfilePrefs|.
    NOTREACHED();
  }

  return static_cast<Availability>(value);
}

#if BUILDFLAG(IS_CHROMEOS)

// Returns true if developer tools availability is set by an active policy in
// |pref_service|.
bool IsDevToolsAvailabilitySetByPolicy(const PrefService* pref_service) {
  return pref_service->IsManagedPreference(prefs::kDevToolsAvailability);
}

// Returns the most restrictive availability within [|availability_1|,
// |availability_2|].
Availability GetMostRestrictiveAvailability(Availability availability_1,
                                            Availability availability_2) {
  if (availability_1 == Availability::kDisallowed ||
      availability_2 == Availability::kDisallowed) {
    return Availability::kDisallowed;
  }
  if (availability_1 == Availability::kDisallowedForForceInstalledExtensions ||
      availability_2 == Availability::kDisallowedForForceInstalledExtensions) {
    return Availability::kDisallowedForForceInstalledExtensions;
  }
  return Availability::kAllowed;
}

#endif

}  // namespace

DeveloperToolsPolicyHandler::DeveloperToolsPolicyHandler() = default;

DeveloperToolsPolicyHandler::~DeveloperToolsPolicyHandler() = default;

bool DeveloperToolsPolicyHandler::CheckPolicySettings(
    const policy::PolicyMap& policies,
    policy::PolicyErrorMap* errors) {
  // It is safe to use `GetValueUnsafe()` because type checking is performed
  // before the value is used.
  // Enumerated policy DeveloperToolsAvailability.
  const base::Value* developer_tools_availability =
      policies.GetValueUnsafe(key::kDeveloperToolsAvailability);
  PolicyCheckResult developer_tools_availability_result =
      CheckDeveloperToolsAvailability(developer_tools_availability, errors);
  PolicyCheckResult developer_tools_disabled_result =
      PolicyCheckResult::kNotSet;
#if !BUILDFLAG(IS_ANDROID)
  // It is safe to use `GetValueUnsafe()` because type checking is performed
  // before the value is used.
  // Deprecated boolean policy DeveloperToolsDisabled.
  const base::Value* developer_tools_disabled =
      policies.GetValueUnsafe(key::kDeveloperToolsDisabled);
  developer_tools_disabled_result =
      CheckDeveloperToolsDisabled(developer_tools_disabled, errors);

  if (developer_tools_disabled_result == PolicyCheckResult::kValid &&
      developer_tools_availability_result == PolicyCheckResult::kValid) {
    errors->AddError(key::kDeveloperToolsDisabled, IDS_POLICY_OVERRIDDEN,
                     key::kDeveloperToolsAvailability);
  }
#endif  // !BUILDFLAG(IS_ANDROID)
  if (developer_tools_disabled_result != PolicyCheckResult::kValid &&
      developer_tools_availability_result != PolicyCheckResult::kValid) {
    return false;
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  const std::optional<Availability> policy = GetValueFromBothPolicies(policies);

  if (policy.has_value() && *policy == Availability::kDisallowed &&
      extension_developer_mode_policy_handler_.IsValidPolicySet(policies)) {
    errors->AddError(key::kDeveloperToolsAvailability,
                     IDS_POLICY_DEVELOPER_TOOLS_EXTENSIONS_CONFLICT_MESSAGE,
                     key::kExtensionDeveloperModeSettings,
                     key::kDeveloperToolsAvailability,
                     /*error_path=*/{}, PolicyMap::MessageType::kInfo);
  }
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)

  // Always continue to ApplyPolicySettings which can handle invalid policy
  // values.
  return true;
}

void DeveloperToolsPolicyHandler::ApplyPolicySettings(const PolicyMap& policies,
                                                      PrefValueMap* prefs) {
  const std::optional<Availability> policy = GetValueFromBothPolicies(policies);

  if (policy.has_value()) {
    prefs->SetInteger(prefs::kDevToolsAvailability, static_cast<int>(*policy));

#if BUILDFLAG(ENABLE_EXTENSIONS)
    // ExtensionDeveloperModePolicySettings takes precedence over this policy.
    // Thus, we only set the value of kExtensionsUIDeveloperMode if the former
    // is not set.
    if (*policy == Availability::kDisallowed &&
        !extension_developer_mode_policy_handler_.IsValidPolicySet(policies)) {
      prefs->SetValue(prefs::kExtensionsUIDeveloperMode, base::Value(false));
    }
#endif  // BUILDFLAG(ENABLE_EXTENSIONS)
  }
}

// static
void DeveloperToolsPolicyHandler::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  // The default for this pref is |kDisallowedForForceInstalledExtensions|, both
  // for managed and for unmanaged users. This is fine for unmanaged users too,
  // because even if they have force-installed extensions (which could happen
  // e.g. through GPO for Chrome on Windows), developer tools should be disabled
  // for these by default.
  registry->RegisterIntegerPref(
      prefs::kDevToolsAvailability,
      static_cast<int>(Availability::kDisallowedForForceInstalledExtensions));
}

policy::DeveloperToolsPolicyHandler::Availability
DeveloperToolsPolicyHandler::GetEffectiveAvailability(Profile* profile) {
#if BUILDFLAG(IS_CHROMEOS)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kForceDevToolsAvailable)) {
    return Availability::kAllowed;
  }
#endif

  Availability availability = GetDevToolsAvailability(profile->GetPrefs());
#if BUILDFLAG(IS_CHROMEOS)
  // Do not create DevTools if it's disabled for primary profile.
  Profile* primary_profile = ProfileManager::GetPrimaryUserProfile();
  if (primary_profile &&
      IsDevToolsAvailabilitySetByPolicy(primary_profile->GetPrefs())) {
    availability = GetMostRestrictiveAvailability(
        availability, GetDevToolsAvailability(primary_profile->GetPrefs()));
  }
#endif
  return availability;
}

}  // namespace policy
