// Copyright 2016 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/site_settings_helper.h"

#include <algorithm>
#include <functional>
#include <set>
#include <string>

#include "base/command_line.h"
#include "base/containers/adapters.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/bluetooth/bluetooth_chooser_context_factory.h"
#include "chrome/browser/content_settings/chrome_content_settings_utils.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/hid/hid_chooser_context.h"
#include "chrome/browser/hid/hid_chooser_context_factory.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/serial/serial_chooser_context.h"
#include "chrome/browser/serial/serial_chooser_context_factory.h"
#include "chrome/browser/subresource_filter/subresource_filter_profile_context_factory.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/permissions/contexts/bluetooth_chooser_context.h"
#include "components/permissions/object_permission_context_base.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "components/permissions/permission_manager.h"
#include "components/permissions/permission_result.h"
#include "components/permissions/permission_util.h"
#include "components/permissions/permissions_client.h"
#include "components/prefs/pref_service.h"
#include "components/subresource_filter/content/browser/subresource_filter_content_settings_manager.h"
#include "components/subresource_filter/content/browser/subresource_filter_profile_context.h"
#include "components/subresource_filter/core/browser/subresource_filter_features.h"
#include "components/url_formatter/url_formatter.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_utils.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/constants.h"
#include "url/origin.h"

namespace site_settings {

constexpr char kAppName[] = "appName";
constexpr char kAppId[] = "appId";

namespace {

// Maps from the UI string to the object it represents (for sorting purposes).
typedef std::multimap<std::string, const base::DictionaryValue*> SortedObjects;

// Maps from a secondary URL to the set of objects it has permission to access.
typedef std::map<GURL, SortedObjects> OneOriginObjects;

// Maps from a primary URL/source pair to a OneOriginObjects. All the mappings
// in OneOriginObjects share the given primary URL and source.
typedef std::map<std::pair<GURL, std::string>, OneOriginObjects>
    AllOriginObjects;

// Chooser data group names.
const char kUsbChooserDataGroupType[] = "usb-devices-data";
const char kSerialChooserDataGroupType[] = "serial-ports-data";
const char kHidChooserDataGroupType[] = "hid-devices-data";
const char kBluetoothChooserDataGroupType[] = "bluetooth-devices-data";

const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = {
    // The following ContentSettingsTypes have UI in Content Settings
    // and require a mapping from their Javascript string representation in
    // chrome/browser/resources/settings/site_settings/constants.js to their C++
    // ContentSettingsType provided here. These group names are only used by
    // desktop webui.
    {ContentSettingsType::COOKIES, "cookies"},
    {ContentSettingsType::IMAGES, "images"},
    {ContentSettingsType::JAVASCRIPT, "javascript"},
    {ContentSettingsType::POPUPS, "popups"},
    {ContentSettingsType::GEOLOCATION, "location"},
    {ContentSettingsType::NOTIFICATIONS, "notifications"},
    {ContentSettingsType::MEDIASTREAM_MIC, "media-stream-mic"},
    {ContentSettingsType::MEDIASTREAM_CAMERA, "media-stream-camera"},
    {ContentSettingsType::PROTOCOL_HANDLERS, "register-protocol-handler"},
    {ContentSettingsType::PPAPI_BROKER, "ppapi-broker"},
    {ContentSettingsType::AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"},
    {ContentSettingsType::MIDI_SYSEX, "midi-sysex"},
    {ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER, "protected-content"},
    {ContentSettingsType::BACKGROUND_SYNC, "background-sync"},
    {ContentSettingsType::ADS, "ads"},
    {ContentSettingsType::SOUND, "sound"},
    {ContentSettingsType::CLIPBOARD_READ_WRITE, "clipboard"},
    {ContentSettingsType::SENSORS, "sensors"},
    {ContentSettingsType::PAYMENT_HANDLER, "payment-handler"},
    {ContentSettingsType::USB_GUARD, "usb-devices"},
    {ContentSettingsType::USB_CHOOSER_DATA, kUsbChooserDataGroupType},
    {ContentSettingsType::IDLE_DETECTION, "idle-detection"},
    {ContentSettingsType::SERIAL_GUARD, "serial-ports"},
    {ContentSettingsType::SERIAL_CHOOSER_DATA, kSerialChooserDataGroupType},
    {ContentSettingsType::BLUETOOTH_SCANNING, "bluetooth-scanning"},
    {ContentSettingsType::HID_GUARD, "hid-devices"},
    {ContentSettingsType::HID_CHOOSER_DATA, kHidChooserDataGroupType},
    {ContentSettingsType::FILE_SYSTEM_WRITE_GUARD, "file-system-write"},
    {ContentSettingsType::MIXEDSCRIPT, "mixed-script"},
    {ContentSettingsType::VR, "vr"},
    {ContentSettingsType::AR, "ar"},
    {ContentSettingsType::BLUETOOTH_GUARD, "bluetooth-devices"},
    {ContentSettingsType::BLUETOOTH_CHOOSER_DATA,
     kBluetoothChooserDataGroupType},
    {ContentSettingsType::WINDOW_PLACEMENT, "window-placement"},
    {ContentSettingsType::FONT_ACCESS, "font-access"},
    {ContentSettingsType::FILE_SYSTEM_ACCESS_CHOOSER_DATA,
     "file-system-access-handles-data"},

    // Add new content settings here if a corresponding Javascript string
    // representation for it is not required, for example if the content setting
    // is not used for desktop. Note some exceptions do have UI in Content
    // Settings but do not require a separate string.
    {ContentSettingsType::DEFAULT, nullptr},
    {ContentSettingsType::AUTO_SELECT_CERTIFICATE, nullptr},
    {ContentSettingsType::SSL_CERT_DECISIONS, nullptr},
    {ContentSettingsType::APP_BANNER, nullptr},
    {ContentSettingsType::SITE_ENGAGEMENT, nullptr},
    {ContentSettingsType::DURABLE_STORAGE, nullptr},
    {ContentSettingsType::AUTOPLAY, nullptr},
    {ContentSettingsType::IMPORTANT_SITE_INFO, nullptr},
    {ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA, nullptr},
    {ContentSettingsType::ADS_DATA, nullptr},
    {ContentSettingsType::MIDI, nullptr},
    {ContentSettingsType::PASSWORD_PROTECTION, nullptr},
    {ContentSettingsType::MEDIA_ENGAGEMENT, nullptr},
    {ContentSettingsType::CLIENT_HINTS, nullptr},
    {ContentSettingsType::ACCESSIBILITY_EVENTS, nullptr},
    {ContentSettingsType::CLIPBOARD_SANITIZED_WRITE, nullptr},
    {ContentSettingsType::BACKGROUND_FETCH, nullptr},
    {ContentSettingsType::INTENT_PICKER_DISPLAY, nullptr},
    {ContentSettingsType::PERIODIC_BACKGROUND_SYNC, nullptr},
    {ContentSettingsType::WAKE_LOCK_SCREEN, nullptr},
    {ContentSettingsType::WAKE_LOCK_SYSTEM, nullptr},
    {ContentSettingsType::LEGACY_COOKIE_ACCESS, nullptr},
    {ContentSettingsType::INSTALLED_WEB_APP_METADATA, nullptr},
    {ContentSettingsType::NFC, nullptr},
    {ContentSettingsType::SAFE_BROWSING_URL_CHECK_DATA, nullptr},
    {ContentSettingsType::FILE_SYSTEM_READ_GUARD, nullptr},
    {ContentSettingsType::STORAGE_ACCESS, nullptr},
    {ContentSettingsType::CAMERA_PAN_TILT_ZOOM, nullptr},
    {ContentSettingsType::INSECURE_PRIVATE_NETWORK, nullptr},
    {ContentSettingsType::PERMISSION_AUTOREVOCATION_DATA, nullptr},
    {ContentSettingsType::FILE_SYSTEM_LAST_PICKED_DIRECTORY, nullptr},
    {ContentSettingsType::DISPLAY_CAPTURE, nullptr},
    {ContentSettingsType::FEDERATED_IDENTITY_SHARING, nullptr},
    {ContentSettingsType::FEDERATED_IDENTITY_REQUEST, nullptr},
    {ContentSettingsType::JAVASCRIPT_JIT, nullptr},
    {ContentSettingsType::HTTP_ALLOWED, nullptr},
    {ContentSettingsType::FORMFILL_METADATA, nullptr},
    {ContentSettingsType::FEDERATED_IDENTITY_ACTIVE_SESSION, nullptr},
    {ContentSettingsType::AUTO_DARK_WEB_CONTENT, nullptr},
    {ContentSettingsType::REQUEST_DESKTOP_SITE, nullptr},
};

static_assert(base::size(kContentSettingsTypeGroupNames) ==
                  // ContentSettingsType starts at -1, so add 1 here.
                  static_cast<int32_t>(ContentSettingsType::NUM_TYPES) + 1,
              "kContentSettingsTypeGroupNames should have "
              "CONTENT_SETTINGS_NUM_TYPES elements");

struct SiteSettingSourceStringMapping {
  SiteSettingSource source;
  const char* source_str;
};

const SiteSettingSourceStringMapping kSiteSettingSourceStringMapping[] = {
    {SiteSettingSource::kAllowlist, "allowlist"},
    {SiteSettingSource::kAdsFilterBlocklist, "ads-filter-blacklist"},
    {SiteSettingSource::kDefault, "default"},
    {SiteSettingSource::kEmbargo, "embargo"},
    {SiteSettingSource::kExtension, "extension"},
    {SiteSettingSource::kHostedApp, "HostedApp"},
    {SiteSettingSource::kInsecureOrigin, "insecure-origin"},
    {SiteSettingSource::kKillSwitch, "kill-switch"},
    {SiteSettingSource::kPolicy, "policy"},
    {SiteSettingSource::kPreference, "preference"},
};
static_assert(base::size(kSiteSettingSourceStringMapping) ==
                  static_cast<int>(SiteSettingSource::kNumSources),
              "kSiteSettingSourceStringMapping should have "
              "SiteSettingSource::kNumSources elements");

struct PolicyIndicatorTypeStringMapping {
  PolicyIndicatorType source;
  const char* indicator_str;
};

// Converts a policy indicator type to its JS usable string representation.
const PolicyIndicatorTypeStringMapping kPolicyIndicatorTypeStringMapping[] = {
    {PolicyIndicatorType::kDevicePolicy, "devicePolicy"},
    {PolicyIndicatorType::kExtension, "extension"},
    {PolicyIndicatorType::kNone, "none"},
    {PolicyIndicatorType::kOwner, "owner"},
    {PolicyIndicatorType::kPrimaryUser, "primary_user"},
    {PolicyIndicatorType::kRecommended, "recommended"},
    {PolicyIndicatorType::kUserPolicy, "userPolicy"},
    {PolicyIndicatorType::kParent, "parent"},
    {PolicyIndicatorType::kChildRestriction, "childRestriction"},
};
static_assert(base::size(kPolicyIndicatorTypeStringMapping) ==
                  static_cast<int>(PolicyIndicatorType::kNumIndicators),
              "kPolicyIndicatorStringMapping should have "
              "PolicyIndicatorType::kNumIndicators elements");

// Retrieves the corresponding string, according to the following precedence
// order from highest to lowest priority:
//    1. Allowlisted WebUI content setting.
//    2. Kill-switch.
//    3. Insecure origins (some permissions are denied to insecure origins).
//    4. Enterprise policy.
//    5. Extensions.
//    6. Activated for ads filtering (for Ads ContentSettingsType only).
//    7. User-set per-origin setting.
//    8. Embargo.
//    9. User-set patterns.
//   10. User-set global default for a ContentSettingsType.
//   11. Chrome's built-in default.
SiteSettingSource CalculateSiteSettingSource(
    Profile* profile,
    const ContentSettingsType content_type,
    const GURL& origin,
    const content_settings::SettingInfo& info,
    const permissions::PermissionResult result) {
  if (info.source == content_settings::SETTING_SOURCE_ALLOWLIST)
    return SiteSettingSource::kAllowlist;  // Source #1.

  if (result.source == permissions::PermissionStatusSource::KILL_SWITCH)
    return SiteSettingSource::kKillSwitch;  // Source #2.

  if (result.source == permissions::PermissionStatusSource::INSECURE_ORIGIN)
    return SiteSettingSource::kInsecureOrigin;  // Source #3.

  if (info.source == content_settings::SETTING_SOURCE_POLICY ||
      info.source == content_settings::SETTING_SOURCE_SUPERVISED) {
    return SiteSettingSource::kPolicy;  // Source #4.
  }

  if (info.source == content_settings::SETTING_SOURCE_EXTENSION)
    return SiteSettingSource::kExtension;  // Source #5.

  if (content_type == ContentSettingsType::ADS &&
      base::FeatureList::IsEnabled(
          subresource_filter::kSafeBrowsingSubresourceFilter)) {
    subresource_filter::SubresourceFilterContentSettingsManager*
        settings_manager =
            SubresourceFilterProfileContextFactory::GetForProfile(profile)
                ->settings_manager();

    if (settings_manager->GetSiteActivationFromMetadata(origin)) {
      return SiteSettingSource::kAdsFilterBlocklist;  // Source #6.
    }
  }

  DCHECK_NE(content_settings::SETTING_SOURCE_NONE, info.source);
  if (info.source == content_settings::SETTING_SOURCE_USER) {
    if (result.source ==
            permissions::PermissionStatusSource::MULTIPLE_DISMISSALS ||
        result.source ==
            permissions::PermissionStatusSource::MULTIPLE_IGNORES) {
      return SiteSettingSource::kEmbargo;  // Source #8.
    }
    if (info.primary_pattern == ContentSettingsPattern::Wildcard() &&
        info.secondary_pattern == ContentSettingsPattern::Wildcard()) {
      return SiteSettingSource::kDefault;  // Source #10, #11.
    }

    // Source #7, #9. When #7 is the source, |result.source| won't be set to
    // any of the source #7 enum values, as PermissionManager is aware of the
    // difference between these two sources internally. The subtlety here should
    // go away when PermissionManager can handle all content settings and all
    // possible sources.
    return SiteSettingSource::kPreference;
  }

  NOTREACHED();
  return SiteSettingSource::kPreference;
}

// Whether |pattern| applies to a single origin.
bool PatternAppliesToSingleOrigin(const ContentSettingPatternSource& pattern) {
  const GURL url(pattern.primary_pattern.ToString());
  // Default settings and other patterns apply to multiple origins.
  if (url::Origin::Create(url).opaque())
    return false;
  // Embedded content settings only match when |url| is embedded in another
  // origin, so ignore non-wildcard secondary patterns.
  if (pattern.secondary_pattern != ContentSettingsPattern::Wildcard()) {
    return false;
  }
  return true;
}

bool PatternAppliesToWebUISchemes(const ContentSettingPatternSource& pattern) {
  return pattern.primary_pattern.GetScheme() ==
             ContentSettingsPattern::SchemeType::SCHEME_CHROME ||
         pattern.primary_pattern.GetScheme() ==
             ContentSettingsPattern::SchemeType::SCHEME_CHROMEUNTRUSTED ||
         pattern.primary_pattern.GetScheme() ==
             ContentSettingsPattern::SchemeType::SCHEME_DEVTOOLS;
}

// Retrieves the source of a chooser exception as a string. This method uses the
// CalculateSiteSettingSource method above to calculate the correct string to
// use.
std::string GetSourceStringForChooserException(
    Profile* profile,
    ContentSettingsType content_type,
    content_settings::SettingSource source) {
  // Prepare the parameters needed by CalculateSiteSettingSource
  content_settings::SettingInfo info;
  info.source = source;

  // Chooser exceptions do not use a PermissionContextBase for their
  // permissions.
  permissions::PermissionResult permission_result(
      CONTENT_SETTING_DEFAULT,
      permissions::PermissionStatusSource::UNSPECIFIED);

  // The |origin| parameter is only used for |ContentSettingsType::ADS| with
  // the |kSafeBrowsingSubresourceFilter| feature flag enabled, so an empty GURL
  // is used.
  SiteSettingSource calculated_source = CalculateSiteSettingSource(
      profile, content_type, /*origin=*/GURL::EmptyGURL(), info,
      permission_result);
  DCHECK(calculated_source == SiteSettingSource::kPolicy ||
         calculated_source == SiteSettingSource::kPreference);
  return SiteSettingSourceToString(calculated_source);
}

permissions::ObjectPermissionContextBase* GetUsbChooserContext(
    Profile* profile) {
  return UsbChooserContextFactory::GetForProfile(profile);
}

permissions::ObjectPermissionContextBase* GetSerialChooserContext(
    Profile* profile) {
  return SerialChooserContextFactory::GetForProfile(profile);
}

permissions::ObjectPermissionContextBase* GetHidChooserContext(
    Profile* profile) {
  return HidChooserContextFactory::GetForProfile(profile);
}

// The BluetoothChooserContext is only available when the
// WebBluetoothNewPermissionsBackend flag is enabled.
// TODO(https://crbug.com/589228): Remove the feature check when it is enabled
// by default.
permissions::ObjectPermissionContextBase* GetBluetoothChooserContext(
    Profile* profile) {
  if (base::FeatureList::IsEnabled(
          features::kWebBluetoothNewPermissionsBackend)) {
    return BluetoothChooserContextFactory::GetForProfile(profile);
  }
  return nullptr;
}

const ChooserTypeNameEntry kChooserTypeGroupNames[] = {
    {&GetUsbChooserContext, kUsbChooserDataGroupType},
    {&GetSerialChooserContext, kSerialChooserDataGroupType},
    {&GetHidChooserContext, kHidChooserDataGroupType},
    {&GetBluetoothChooserContext, kBluetoothChooserDataGroupType}};

}  // namespace

bool HasRegisteredGroupName(ContentSettingsType type) {
  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
    if (type == kContentSettingsTypeGroupNames[i].type &&
        kContentSettingsTypeGroupNames[i].name) {
      return true;
    }
  }
  return false;
}

ContentSettingsType ContentSettingsTypeFromGroupName(base::StringPiece name) {
  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
    if (name == kContentSettingsTypeGroupNames[i].name)
      return kContentSettingsTypeGroupNames[i].type;
  }

  NOTREACHED() << name << " is not a recognized content settings type.";
  return ContentSettingsType::DEFAULT;
}

base::StringPiece ContentSettingsTypeToGroupName(ContentSettingsType type) {
  for (size_t i = 0; i < base::size(kContentSettingsTypeGroupNames); ++i) {
    if (type == kContentSettingsTypeGroupNames[i].type) {
      const char* name = kContentSettingsTypeGroupNames[i].name;
      if (name)
        return name;
      break;
    }
  }

  NOTREACHED() << static_cast<int32_t>(type)
               << " is not a recognized content settings type.";
  return base::StringPiece();
}

const std::vector<ContentSettingsType>& GetVisiblePermissionCategories() {
  // First build the list of permissions that will be shown regardless of
  // `origin`. Some categories such as COOKIES store their data in a custom way,
  // so are not included here.
  static base::NoDestructor<std::vector<ContentSettingsType>> base_types{{
      ContentSettingsType::AR,
      ContentSettingsType::AUTOMATIC_DOWNLOADS,
      ContentSettingsType::BACKGROUND_SYNC,
      ContentSettingsType::CLIPBOARD_READ_WRITE,
      ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
      ContentSettingsType::FONT_ACCESS,
      ContentSettingsType::GEOLOCATION,
      ContentSettingsType::HID_GUARD,
      ContentSettingsType::IDLE_DETECTION,
      ContentSettingsType::IMAGES,
      ContentSettingsType::JAVASCRIPT,
      ContentSettingsType::MEDIASTREAM_CAMERA,
      ContentSettingsType::MEDIASTREAM_MIC,
      ContentSettingsType::MIDI_SYSEX,
      ContentSettingsType::MIXEDSCRIPT,
      ContentSettingsType::NOTIFICATIONS,
      ContentSettingsType::POPUPS,
#if defined(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN)
      ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER,
#endif
      ContentSettingsType::SENSORS,
      ContentSettingsType::SERIAL_GUARD,
      ContentSettingsType::SOUND,
      ContentSettingsType::USB_GUARD,
      ContentSettingsType::VR,
      ContentSettingsType::WINDOW_PLACEMENT,
  }};
  static bool initialized = false;
  if (!initialized) {
    // The permission categories in this block are only shown when running with
    // certain flags/switches.
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            ::switches::kEnableExperimentalWebPlatformFeatures)) {
      base_types->push_back(ContentSettingsType::BLUETOOTH_SCANNING);
    }

    if (base::FeatureList::IsEnabled(::features::kServiceWorkerPaymentApps))
      base_types->push_back(ContentSettingsType::PAYMENT_HANDLER);

    if (base::FeatureList::IsEnabled(
            features::kWebBluetoothNewPermissionsBackend)) {
      base_types->push_back(ContentSettingsType::BLUETOOTH_GUARD);
    }

    if (base::FeatureList::IsEnabled(
            subresource_filter::kSafeBrowsingSubresourceFilter)) {
      base_types->push_back(ContentSettingsType::ADS);
    }

    initialized = true;
  }

  return *base_types;
}

std::string SiteSettingSourceToString(const SiteSettingSource source) {
  return kSiteSettingSourceStringMapping[static_cast<int>(source)].source_str;
}

base::Value GetValueForManagedState(const site_settings::ManagedState& state) {
  base::Value value(base::Value::Type::DICTIONARY);
  value.SetKey(site_settings::kDisabled, base::Value(state.disabled));
  value.SetKey(
      site_settings::kPolicyIndicator,
      base::Value(site_settings::PolicyIndicatorTypeToString(state.indicator)));
  return value;
}

// Add an "Allow"-entry to the list of |exceptions| for a |url_pattern| from
// the web extent of a hosted |app|.
void AddExceptionForHostedApp(const std::string& url_pattern,
                              const extensions::Extension& app,
                              base::ListValue* exceptions) {
  std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue());

  std::string setting_string =
      content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW);
  DCHECK(!setting_string.empty());

  exception->SetString(kSetting, setting_string);
  exception->SetString(kOrigin, url_pattern);
  exception->SetString(kDisplayName, url_pattern);
  exception->SetString(kEmbeddingOrigin, url_pattern);
  exception->SetString(
      kSource, SiteSettingSourceToString(SiteSettingSource::kHostedApp));
  exception->SetBoolean(kIncognito, false);
  exception->SetString(kAppName, app.name());
  exception->SetString(kAppId, app.id());
  exceptions->Append(std::move(exception));
}

// Create a DictionaryValue* that will act as a data source for a single row
// in a HostContentSettingsMap-controlled exceptions table (e.g., cookies).
std::unique_ptr<base::DictionaryValue> GetExceptionForPage(
    ContentSettingsType content_type,
    Profile* profile,
    const ContentSettingsPattern& pattern,
    const ContentSettingsPattern& secondary_pattern,
    const std::string& display_name,
    const ContentSetting& setting,
    const std::string& provider_name,
    bool incognito,
    bool is_embargoed) {
  auto exception = std::make_unique<base::DictionaryValue>();
  exception->SetString(kOrigin, pattern.ToString());
  exception->SetString(kDisplayName, display_name);
  exception->SetString(kEmbeddingOrigin,
                       secondary_pattern == ContentSettingsPattern::Wildcard()
                           ? std::string()
                           : secondary_pattern.ToString());

  std::string setting_string =
      content_settings::ContentSettingToString(setting);
  DCHECK(!setting_string.empty());
  exception->SetString(kSetting, setting_string);

  exception->SetString(kSource, provider_name);
  exception->SetBoolean(kIncognito, incognito);
  exception->SetBoolean(kIsEmbargoed, is_embargoed);
  return exception;
}

std::string GetDisplayNameForExtension(
    const GURL& url,
    const extensions::ExtensionRegistry* extension_registry) {
  if (extension_registry && url.SchemeIs(extensions::kExtensionScheme)) {
    // For the extension scheme, the pattern must be a valid URL.
    DCHECK(url.is_valid());
    const extensions::Extension* extension =
        extension_registry->GetExtensionById(
            url.host(), extensions::ExtensionRegistry::EVERYTHING);
    if (extension)
      return extension->name();
  }
  return std::string();
}

// Takes |url| and converts it into an individual origin string or retrieves
// name of the extension it belongs to.
std::string GetDisplayNameForGURL(
    const GURL& url,
    const extensions::ExtensionRegistry* extension_registry) {
  const url::Origin origin = url::Origin::Create(url);
  if (origin.opaque())
    return url.spec();

  std::string display_name =
      GetDisplayNameForExtension(url, extension_registry);
  if (!display_name.empty())
    return display_name;

  auto url_16 = url_formatter::FormatUrl(
      url,
      url_formatter::kFormatUrlOmitDefaults |
          url_formatter::kFormatUrlOmitHTTPS |
          url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname,
      net::UnescapeRule::NONE, nullptr, nullptr, nullptr);
  auto url_string = base::UTF16ToUTF8(url_16);
  return url_string;
}

// If the given |pattern| represents an individual origin or extension, retrieve
// a string to display it as such. If not, return the pattern as a string.
std::string GetDisplayNameForPattern(
    const ContentSettingsPattern& pattern,
    const extensions::ExtensionRegistry* extension_registry) {
  const GURL url(pattern.ToString());
  const std::string extension_display_name =
      GetDisplayNameForExtension(url, extension_registry);
  if (!extension_display_name.empty())
    return extension_display_name;
  return pattern.ToString();
}

void GetExceptionsForContentType(
    ContentSettingsType type,
    Profile* profile,
    const extensions::ExtensionRegistry* extension_registry,
    content::WebUI* web_ui,
    bool incognito,
    base::ListValue* exceptions) {
  ContentSettingsForOneType all_settings;
  HostContentSettingsMap* map =
      HostContentSettingsMapFactory::GetForProfile(profile);

  map->GetSettingsForOneType(type, &all_settings);

  // Group settings by primary_pattern.
  AllPatternsSettings all_patterns_settings;
  for (const auto& setting : all_settings) {
    // Don't add default settings.
    if (setting.primary_pattern == ContentSettingsPattern::Wildcard() &&
        setting.secondary_pattern == ContentSettingsPattern::Wildcard() &&
        setting.source !=
            SiteSettingSourceToString(SiteSettingSource::kPreference)) {
      continue;
    }

    // Off-the-record HostContentSettingsMap contains incognito content settings
    // as well as normal content settings. Here, we use the incognito settings
    // only.
    if (map->IsOffTheRecord() && !setting.incognito)
      continue;

    // Don't add WebUI settings.
    if (PatternAppliesToWebUISchemes(setting)) {
      continue;
    }

    all_patterns_settings[std::make_pair(
        setting.primary_pattern, setting.source)][setting.secondary_pattern] =
        setting.GetContentSetting();
  }

  ContentSettingsForOneType embargo_settings;
  map->GetSettingsForOneType(ContentSettingsType::PERMISSION_AUTOBLOCKER_DATA,
                             &embargo_settings);

  permissions::PermissionDecisionAutoBlocker* auto_blocker =
      permissions::PermissionsClient::Get()->GetPermissionDecisionAutoBlocker(
          profile);

  std::set<ContentSettingsPattern> origins_under_embargo;

  for (const auto& setting : embargo_settings) {
    // Off-the-record HostContentSettingsMap contains incognito content
    // settings as well as normal content settings. Here, we use the
    // incognito settings only.
    if (map->IsOffTheRecord() && !setting.incognito)
      continue;

    if (!permissions::PermissionUtil::IsPermission(type))
      continue;

    if (auto_blocker
            ->GetEmbargoResult(GURL(setting.primary_pattern.ToString()), type)
            .content_setting == CONTENT_SETTING_BLOCK) {
      origins_under_embargo.insert(setting.primary_pattern);
      all_patterns_settings[std::make_pair(
          setting.primary_pattern, setting.source)][setting.secondary_pattern] =
          CONTENT_SETTING_BLOCK;
    }
  }

  // Keep the exceptions sorted by provider so they will be displayed in
  // precedence order.
  std::vector<std::unique_ptr<base::DictionaryValue>>
      all_provider_exceptions[HostContentSettingsMap::NUM_PROVIDER_TYPES];

  // |all_patterns_settings| is sorted from the lowest precedence pattern to
  // the highest (see operator< in ContentSettingsPattern), so traverse it in
  // reverse to show the patterns with the highest precedence (the more specific
  // ones) on the top.
  for (const auto& [primary_pattern_and_source, one_settings] :
       base::Reversed(all_patterns_settings)) {
    const auto& [primary_pattern, source] = primary_pattern_and_source;
    const std::string display_name =
        GetDisplayNameForPattern(primary_pattern, extension_registry);

    // The "parent" entry either has an identical primary and secondary pattern,
    // or has a wildcard secondary. The two cases are indistinguishable in the
    // UI.
    auto parent = one_settings.find(primary_pattern);
    if (parent == one_settings.end())
      parent = one_settings.find(ContentSettingsPattern::Wildcard());

    auto& this_provider_exceptions = all_provider_exceptions
        [HostContentSettingsMap::GetProviderTypeFromSource(source)];

    // Add the "parent" entry for the non-embedded setting.
    ContentSetting parent_setting =
        parent == one_settings.end() ? CONTENT_SETTING_DEFAULT : parent->second;
    const ContentSettingsPattern& secondary_pattern =
        parent == one_settings.end() ? primary_pattern : parent->first;
    this_provider_exceptions.push_back(GetExceptionForPage(
        type, profile, primary_pattern, secondary_pattern, display_name,
        parent_setting, source, incognito,
        base::Contains(origins_under_embargo, primary_pattern)));

    // Add the "children" for any embedded settings.
    for (auto j = one_settings.begin(); j != one_settings.end(); ++j) {
      // Skip the non-embedded setting which we already added above.
      if (j == parent)
        continue;

      ContentSetting content_setting = j->second;
      this_provider_exceptions.push_back(GetExceptionForPage(
          type, profile, primary_pattern, j->first, display_name,
          content_setting, source, incognito,
          base::Contains(origins_under_embargo, primary_pattern)));
    }
  }

  // For camera and microphone, we do not have policy exceptions, but we do have
  // the policy-set allowed URLs, which should be displayed in the same manner.
  if (type == ContentSettingsType::MEDIASTREAM_MIC ||
      type == ContentSettingsType::MEDIASTREAM_CAMERA) {
    auto& policy_exceptions = all_provider_exceptions
        [HostContentSettingsMap::GetProviderTypeFromSource(
            SiteSettingSourceToString(SiteSettingSource::kPolicy))];
    DCHECK(policy_exceptions.empty());
    GetPolicyAllowedUrls(type, &policy_exceptions, extension_registry, web_ui,
                         incognito);
  }

  for (auto& one_provider_exceptions : all_provider_exceptions) {
    for (auto& exception : one_provider_exceptions)
      exceptions->Append(std::move(exception));
  }
}

void GetContentCategorySetting(const HostContentSettingsMap* map,
                               ContentSettingsType content_type,
                               base::DictionaryValue* object) {
  std::string provider;
  std::string setting = content_settings::ContentSettingToString(
      map->GetDefaultContentSetting(content_type, &provider));
  DCHECK(!setting.empty());

  object->SetString(kSetting, setting);
  if (provider != SiteSettingSourceToString(SiteSettingSource::kDefault))
    object->SetString(kSource, provider);
}

ContentSetting GetContentSettingForOrigin(
    Profile* profile,
    const HostContentSettingsMap* map,
    const GURL& origin,
    ContentSettingsType content_type,
    std::string* source_string,
    const extensions::ExtensionRegistry* extension_registry,
    std::string* display_name) {
  // TODO(patricialor): In future, PermissionManager should know about all
  // content settings, not just the permissions, plus all the possible sources,
  // and the calls to HostContentSettingsMap should be removed.
  content_settings::SettingInfo info;
  const base::Value value =
      map->GetWebsiteSetting(origin, origin, content_type, &info);

  // Retrieve the content setting.
  permissions::PermissionResult result(
      CONTENT_SETTING_DEFAULT,
      permissions::PermissionStatusSource::UNSPECIFIED);
  if (permissions::PermissionUtil::IsPermission(content_type)) {
    result =
        PermissionManagerFactory::GetForProfile(profile)->GetPermissionStatus(
            content_type, origin, origin);
  } else {
    DCHECK_EQ(base::Value::Type::INTEGER, value.type());
    result.content_setting = content_settings::ValueToContentSetting(value);
  }

  // Retrieve the source of the content setting.
  *source_string = SiteSettingSourceToString(
      CalculateSiteSettingSource(profile, content_type, origin, info, result));
  *display_name = GetDisplayNameForGURL(origin, extension_registry);

  if (info.session_model == content_settings::SessionModel::OneTime) {
    DCHECK_EQ(content_type, ContentSettingsType::GEOLOCATION);
    DCHECK_EQ(result.content_setting, CONTENT_SETTING_ALLOW);
    return CONTENT_SETTING_DEFAULT;
  }
  return result.content_setting;
}

std::vector<ContentSettingPatternSource> GetSiteExceptionsForContentType(
    HostContentSettingsMap* map,
    ContentSettingsType content_type) {
  ContentSettingsForOneType entries;
  map->GetSettingsForOneType(content_type, &entries);
  entries.erase(std::remove_if(entries.begin(), entries.end(),
                               [](const ContentSettingPatternSource& e) {
                                 return !PatternAppliesToSingleOrigin(e) ||
                                        PatternAppliesToWebUISchemes(e);
                               }),
                entries.end());
  return entries;
}

void GetPolicyAllowedUrls(
    ContentSettingsType type,
    std::vector<std::unique_ptr<base::DictionaryValue>>* exceptions,
    const extensions::ExtensionRegistry* extension_registry,
    content::WebUI* web_ui,
    bool incognito) {
  DCHECK(type == ContentSettingsType::MEDIASTREAM_MIC ||
         type == ContentSettingsType::MEDIASTREAM_CAMERA);

  Profile* profile = Profile::FromWebUI(web_ui);
  PrefService* prefs = profile->GetPrefs();
  const base::Value* policy_urls =
      prefs->GetList(type == ContentSettingsType::MEDIASTREAM_MIC
                         ? prefs::kAudioCaptureAllowedUrls
                         : prefs::kVideoCaptureAllowedUrls);

  // Convert the URLs to |ContentSettingsPattern|s. Ignore any invalid ones.
  std::vector<ContentSettingsPattern> patterns;
  for (const auto& entry : policy_urls->GetList()) {
    const std::string* url = entry.GetIfString();
    if (!url)
      continue;

    ContentSettingsPattern pattern = ContentSettingsPattern::FromString(*url);
    if (!pattern.IsValid())
      continue;

    patterns.push_back(pattern);
  }

  // The patterns are shown in the UI in a reverse order defined by
  // |ContentSettingsPattern::operator<|.
  std::sort(patterns.begin(), patterns.end(),
            std::greater<ContentSettingsPattern>());

  for (const ContentSettingsPattern& pattern : patterns) {
    std::string display_name =
        GetDisplayNameForPattern(pattern, extension_registry);
    exceptions->push_back(GetExceptionForPage(
        type, profile, pattern, ContentSettingsPattern(), display_name,
        CONTENT_SETTING_ALLOW,
        SiteSettingSourceToString(SiteSettingSource::kPolicy), incognito));
  }
}

const ChooserTypeNameEntry* ChooserTypeFromGroupName(const std::string& name) {
  for (const auto& chooser_type : kChooserTypeGroupNames) {
    if (chooser_type.name == name)
      return &chooser_type;
  }
  return nullptr;
}

// Create a DictionaryValue* that will act as a data source for a single row
// in a chooser permission exceptions table. The chooser permission will contain
// a list of site exceptions that correspond to the exception.
base::Value CreateChooserExceptionObject(
    const std::u16string& display_name,
    const base::Value& object,
    const std::string& chooser_type,
    const ChooserExceptionDetails& chooser_exception_details) {
  base::Value exception(base::Value::Type::DICTIONARY);

  std::string setting_string =
      content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT);
  DCHECK(!setting_string.empty());

  exception.SetStringKey(kDisplayName, display_name);
  exception.SetKey(kObject, object.Clone());
  exception.SetStringKey(kChooserType, chooser_type);

  // Order the sites by the provider precedence order.
  std::vector<base::Value>
      all_provider_sites[HostContentSettingsMap::NUM_PROVIDER_TYPES];
  for (const auto& details : chooser_exception_details) {
    const GURL& requesting_origin = details.first.first;
    const std::string& source = details.first.second;

    auto& this_provider_sites =
        all_provider_sites[HostContentSettingsMap::GetProviderTypeFromSource(
            source)];

    for (const auto& embedding_origin_incognito_pair : details.second) {
      const GURL& embedding_origin = embedding_origin_incognito_pair.first;
      const bool incognito = embedding_origin_incognito_pair.second;
      base::Value site(base::Value::Type::DICTIONARY);

      site.SetStringKey(kOrigin, requesting_origin.spec());
      site.SetStringKey(kDisplayName, requesting_origin.spec());
      site.SetStringKey(kEmbeddingOrigin, embedding_origin.is_empty()
                                              ? std::string()
                                              : embedding_origin.spec());
      site.SetStringKey(kSetting, setting_string);
      site.SetStringKey(kSource, source);
      site.SetBoolKey(kIncognito, incognito);
      this_provider_sites.push_back(std::move(site));
    }
  }

  base::Value sites(base::Value::Type::LIST);
  for (auto& one_provider_sites : all_provider_sites) {
    for (auto& site : one_provider_sites) {
      sites.Append(std::move(site));
    }
  }

  exception.SetKey(kSites, std::move(sites));
  return exception;
}

base::Value GetChooserExceptionListFromProfile(
    Profile* profile,
    const ChooserTypeNameEntry& chooser_type) {
  base::Value exceptions(base::Value::Type::LIST);
  ContentSettingsType content_type =
      ContentSettingsTypeFromGroupName(std::string(chooser_type.name));

  // The BluetoothChooserContext is only available when the
  // WebBluetoothNewPermissionsBackend flag is enabled.
  // TODO(https://crbug.com/589228): Remove the nullptr check when it is enabled
  // by default.
  permissions::ObjectPermissionContextBase* chooser_context =
      chooser_type.get_context(profile);
  if (!chooser_context)
    return exceptions;

  std::vector<std::unique_ptr<permissions::ObjectPermissionContextBase::Object>>
      objects = chooser_context->GetAllGrantedObjects();

  if (profile->HasPrimaryOTRProfile()) {
    Profile* incognito_profile =
        profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
    permissions::ObjectPermissionContextBase* incognito_chooser_context =
        chooser_type.get_context(incognito_profile);
    std::vector<
        std::unique_ptr<permissions::ObjectPermissionContextBase::Object>>
        incognito_objects = incognito_chooser_context->GetAllGrantedObjects();
    objects.insert(objects.end(),
                   std::make_move_iterator(incognito_objects.begin()),
                   std::make_move_iterator(incognito_objects.end()));
  }

  // Maps from a chooser exception name/object pair to a
  // ChooserExceptionDetails. This will group and sort the exceptions by the UI
  // string and object for display.
  std::map<std::pair<std::u16string, base::Value>, ChooserExceptionDetails>
      all_chooser_objects;
  for (const auto& object : objects) {
    // Don't include WebUI settings.
    if (content::HasWebUIScheme(object->origin))
      continue;

    std::u16string name = chooser_context->GetObjectDisplayName(object->value);
    auto& chooser_exception_details =
        all_chooser_objects[std::make_pair(name, object->value.Clone())];

    std::string source = GetSourceStringForChooserException(
        profile, content_type, object->source);

    const auto origin_source_pair = std::make_pair(object->origin, source);
    auto& origin_incognito_pair_set =
        chooser_exception_details[origin_source_pair];

    const auto origin_incognito_pair =
        std::make_pair(object->origin, object->incognito);
    origin_incognito_pair_set.insert(origin_incognito_pair);
  }

  for (const auto& all_chooser_objects_entry : all_chooser_objects) {
    const std::u16string& name = all_chooser_objects_entry.first.first;
    const base::Value& object = all_chooser_objects_entry.first.second;
    const ChooserExceptionDetails& chooser_exception_details =
        all_chooser_objects_entry.second;
    exceptions.Append(CreateChooserExceptionObject(
        name, object, chooser_type.name, chooser_exception_details));
  }

  return exceptions;
}

std::string PolicyIndicatorTypeToString(const PolicyIndicatorType type) {
  return kPolicyIndicatorTypeStringMapping[static_cast<int>(type)]
      .indicator_str;
}

PolicyIndicatorType GetPolicyIndicatorFromPref(
    const PrefService::Preference* pref) {
  if (!pref) {
    return PolicyIndicatorType::kNone;
  }
  if (pref->IsExtensionControlled()) {
    return PolicyIndicatorType::kExtension;
  }
  if (pref->IsManagedByCustodian()) {
    return PolicyIndicatorType::kParent;
  }
  if (pref->IsManaged()) {
    return PolicyIndicatorType::kDevicePolicy;
  }
  if (pref->GetRecommendedValue()) {
    return PolicyIndicatorType::kRecommended;
  }
  return PolicyIndicatorType::kNone;
}

}  // namespace site_settings
