// Copyright 2013 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/extensions/extension_util.h"

#include <string_view>
#include <vector>

#include "base/check_is_test.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/permissions/permissions_updater.h"
#include "chrome/browser/extensions/shared_module_service.h"
#include "chrome/browser/extensions/sync/extension_sync_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
#include "chrome/common/extensions/sync_helper.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/variations/variations_associated_data.h"
#include "content/public/browser/site_instance.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/pref_names.h"
#include "extensions/browser/renderer_startup_helper.h"
#include "extensions/browser/updater/scoped_extension_updater_keep_alive.h"
#include "extensions/browser/user_script_manager.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
#include "extensions/common/features/feature_developer_mode_only.h"
#include "extensions/common/icons/extension_icon_set.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h"
#include "ui/gfx/text_constants.h"
#include "ui/gfx/text_elider.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chromeos/ash/components/file_manager/app_id.h"
#endif

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/browser.h"
#endif

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace extensions::util {

namespace {

bool ExtensionsDisabledViaCommandLine(const base::CommandLine& command_line) {
  return command_line.HasSwitch(switches::kDisableExtensions) ||
         command_line.HasSwitch(switches::kDisableExtensionsExcept);
}

// Returns |extension_id|. See note below.
std::string ReloadExtension(const std::string& extension_id,
                            content::BrowserContext* context) {
  // When we reload the extension the ID may be invalidated if we've passed it
  // by const ref everywhere. Make a copy to be safe. http://crbug.com/103762
  std::string id = extension_id;
  ExtensionRegistrar::Get(context)->ReloadExtension(extension_id);
  return id;
}

std::string ReloadExtensionIfEnabled(const std::string& extension_id,
                                     content::BrowserContext* context) {
  ExtensionRegistry* registry = ExtensionRegistry::Get(context);
  bool extension_is_enabled =
      registry->enabled_extensions().Contains(extension_id);

  if (!extension_is_enabled) {
    return extension_id;
  }
  return ReloadExtension(extension_id, context);
}

#if BUILDFLAG(IS_CHROMEOS)
// Returns true if the extension ID is found in the InstallForceList policy. Is
// checked by HasIsolatedStorage() when the extension is not found in the
// registry.
bool IsForceInstalledExtension(const ExtensionId& extension_id,
                               content::BrowserContext* context) {
  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context);
  const PrefService::Preference* const pref =
      extension_prefs->pref_service()->FindPreference(
          pref_names::kInstallForceList);
  if (!pref || !pref->IsManaged() ||
      pref->GetType() != base::Value::Type::DICT) {
    return false;
  }
  for (const auto item : pref->GetValue()->GetDict()) {
    if (extension_id == item.first) {
      return true;
    }
  }
  return false;
}
#endif  // BUILDFLAG(IS_CHROMEOS)

// Returns true if the profile is a sign-in profile and the extension is policy
// installed. `is_policy_installed` can be passed to the method if its value is
// known (i.e. the extension was found in the registry and the extension
// location was checked). If no value is passed for `is_policy_installed`, the
// force-installed list will be queried for the extension ID.
bool IsLoginScreenExtension(
    ExtensionId extension_id,
    content::BrowserContext* context,
    std::optional<bool> is_policy_installed = std::nullopt) {
#if BUILDFLAG(IS_CHROMEOS)
  // Verify the force-installed extension list if no value for
  // `is_policy_installed` was passed.
  if (is_policy_installed == std::nullopt) {
    is_policy_installed = IsForceInstalledExtension(extension_id, context);
  }
  Profile* profile = Profile::FromBrowserContext(context);
  return profile && ash::ProfileHelper::IsSigninProfile(profile) &&
         is_policy_installed.value();
#else
  return false;
#endif
}

#if BUILDFLAG(IS_CHROMEOS)
bool IsPolicyInstalled(const ExtensionId& extension_id,
                       content::BrowserContext* context) {
  const Extension* extension =
      ExtensionRegistry::Get(context)->GetInstalledExtension(extension_id);
  if (!extension) {
    return false;
  }

  return Manifest::IsPolicyLocation(extension->location());
}
#endif
}  // namespace

bool HasIsolatedStorage(const ExtensionId& extension_id,
                        content::BrowserContext* context) {
  const Extension* extension =
      ExtensionRegistry::Get(context)->GetInstalledExtension(extension_id);
  // Extension is null when the extension is cleaned up after it's unloaded and
  // won't be present in the ExtensionRegistry.
  return extension ? HasIsolatedStorage(*extension, context)
                   : IsLoginScreenExtension(extension_id, context);
}

bool HasIsolatedStorage(const Extension& extension,
                        content::BrowserContext* context) {
#if BUILDFLAG(IS_CHROMEOS)
  const bool is_policy_extension =
      Manifest::IsPolicyLocation(extension.location());
  if (IsLoginScreenExtension(extension.id(), context, is_policy_extension)) {
    return true;
  }
#endif

  return extension.is_platform_app();
}

void SetIsIncognitoEnabled(const std::string& extension_id,
                           content::BrowserContext* context,
                           bool enabled) {
  ExtensionRegistry* registry = ExtensionRegistry::Get(context);
  const Extension* extension =
      registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);

  if (extension) {
    if (!util::CanBeIncognitoEnabled(extension)) {
      return;
    }

    // TODO(crbug.com/356905053): Enable handling component extensions on
    // desktop android.
#if !BUILDFLAG(IS_ANDROID)
    // TODO(treib,kalman): Should this be Manifest::IsComponentLocation(..)?
    // (which also checks for kExternalComponent).
    if (extension->location() == mojom::ManifestLocation::kComponent) {
      // This shouldn't be called for component extensions unless it is called
      // by sync, for syncable component extensions.
      // See http://crbug.com/112290 and associated CLs for the sordid history.
      bool syncable = sync_helper::IsSyncableComponentExtension(extension);
#if BUILDFLAG(IS_CHROMEOS)
      // For some users, the file manager app somehow ended up being synced even
      // though it's supposed to be unsyncable; see crbug.com/576964. If the bad
      // data ever gets cleaned up, this hack should be removed.
      syncable = syncable || extension->id() == file_manager::kFileManagerAppId;
#endif
      DCHECK(syncable);

      // If we are here, make sure the we aren't trying to change the value.
      DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, context));
      return;
    }
#endif  // !BUILDFLAG(IS_ANDROID)
  }

  ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context);
#if BUILDFLAG(IS_CHROMEOS)
  // Admin installed extensions should not be restartable, so we will apply the
  // change when Chrome restarts.
  if (IsPolicyInstalled(extension_id, context)) {
    extension_prefs->SetIsIncognitoEnabledDelayed(extension_id, enabled);
    return;
  }
#endif
  // Broadcast unloaded and loaded events to update browser state. Only bother
  // if the value changed and the extension is actually enabled, since there is
  // no UI otherwise.
  bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id);
  if (enabled == old_enabled) {
    return;
  }

  extension_prefs->SetIsIncognitoEnabled(extension_id, enabled);

  std::string id = ReloadExtensionIfEnabled(extension_id, context);

  // Reloading the extension invalidates the |extension| pointer.
  extension = registry->GetExtensionById(id, ExtensionRegistry::EVERYTHING);
  if (extension) {
    Profile* profile = Profile::FromBrowserContext(context);
    ExtensionSyncService::Get(profile)->SyncExtensionChangeIfNeeded(*extension);
  }
}

void SetAllowFileAccess(const std::string& extension_id,
                        content::BrowserContext* context,
                        bool allow) {
#if BUILDFLAG(IS_CHROMEOS)
  // Admin installed extensions should not be restartable, so we will apply the
  // change when Chrome restarts.
  if (IsPolicyInstalled(extension_id, context)) {
    ExtensionPrefs::Get(context)->SetAllowFileAccessDelayed(extension_id,
                                                            allow);
    return;
  }
#endif
  // Reload to update browser state if the value changed. We need to reload even
  // if the extension is disabled, in order to make sure file access is
  // reinitialized correctly.
  if (allow == util::AllowFileAccess(extension_id, context)) {
    return;
  }

  ExtensionPrefs::Get(context)->SetAllowFileAccess(extension_id, allow);

  ReloadExtension(extension_id, context);
}

base::Value::Dict GetExtensionInfo(const Extension* extension) {
  DCHECK(extension);
  base::Value::Dict dict;

  dict.Set("id", extension->id());
  dict.Set("name", extension->name());

  GURL icon = extensions::ExtensionIconSource::GetIconURL(
      extension, extension_misc::EXTENSION_ICON_SMALLISH,
      ExtensionIconSet::Match::kBigger,
      /*grayscale=*/false);
  dict.Set("icon", icon.spec());

  return dict;
}

std::unique_ptr<const PermissionSet> GetInstallPromptPermissionSetForExtension(
    const Extension* extension,
    Profile* profile) {
  // Initialize permissions if they have not already been set so that
  // any transformations are correctly reflected in the install prompt.
  PermissionsUpdater(profile, PermissionsUpdater::INIT_FLAG_TRANSIENT)
      .InitializePermissions(extension);

  return extension->permissions_data()->active_permissions().Clone();
}

std::vector<content::BrowserContext*> GetAllRelatedProfiles(
    Profile* profile,
    const Extension& extension) {
  std::vector<content::BrowserContext*> related_contexts;
  related_contexts.push_back(profile->GetOriginalProfile());

  // The returned `related_contexts` should include all the related incognito
  // profiles if the extension is globally allowed in incognito (this is a
  // global, rather than per-profile toggle - this is why we it can be checked
  // globally here, rather than once for every incognito profile looped over
  // below).
  if (IsIncognitoEnabled(extension.id(), profile)) {
    std::vector<Profile*> off_the_record_profiles =
        profile->GetAllOffTheRecordProfiles();
    related_contexts.reserve(related_contexts.size() +
                             off_the_record_profiles.size());
    for (Profile* off_the_record_profile : off_the_record_profiles)
      related_contexts.push_back(off_the_record_profile);
  }

  return related_contexts;
}

void SetDeveloperModeForProfile(Profile* profile, bool in_developer_mode) {
  profile->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode,
                                  in_developer_mode);
  SetCurrentDeveloperMode(util::GetBrowserContextId(profile),
                          in_developer_mode);
  RendererStartupHelperFactory::GetForBrowserContext(profile)
      ->OnDeveloperModeChanged(in_developer_mode);

  // kDynamicUserScript scripts are allowed if and only if the user is in dev
  // mode (since they allow raw code execution). Notify the user script manager
  // to properly enable or disable any scripts.
  UserScriptManager* user_script_manager =
      ExtensionSystem::Get(profile)->user_script_manager();
  if (!user_script_manager) {
    CHECK_IS_TEST();  // `user_script_manager` can be null in unit tests.
    return;
  }

  user_script_manager->SetUserScriptSourceEnabledForExtensions(
      UserScript::Source::kDynamicUserScript, in_developer_mode);
}

std::u16string GetFixupExtensionNameForUIDisplay(
    const std::u16string& extension_name) {
  const size_t extension_name_char_limit =
      75;  // Extension name char limit on CWS
  gfx::BreakType break_type = gfx::BreakType::CHARACTER_BREAK;
  std::u16string fixup_extension_name = gfx::TruncateString(
      extension_name, extension_name_char_limit, break_type);
  return fixup_extension_name;
}

std::u16string GetFixupExtensionNameForUIDisplay(
    const std::string& extension_name) {
  return GetFixupExtensionNameForUIDisplay(base::UTF8ToUTF16(extension_name));
}

void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(prefs::kShouldGarbageCollectStoragePartitions,
                                false);
}

bool AreExtensionsDisabled(const base::CommandLine& command_line,
                           content::BrowserContext* context) {
  Profile* profile = Profile::FromBrowserContext(context);
  return ExtensionsDisabledViaCommandLine(command_line) ||
         profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions);
}

} // namespace extensions::util
