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

#include "content/public/common/content_switch_dependent_feature_overrides.h"

#include "content/common/features.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "net/base/features.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/switches.h"
#include "ui/gfx/switches.h"

namespace content {

std::vector<base::FeatureList::FeatureOverrideInfo>
GetSwitchDependentFeatureOverrides(const base::CommandLine& command_line) {
  // Describes a switch-dependent override.
  struct SwitchDependentFeatureOverrideInfo {
    // Switch that the override depends upon. The override will be registered if
    // this switch is present.
    const char* switch_name;
    // Feature to override.
    const std::reference_wrapper<const base::Feature> feature;
    // State to override the feature with.
    base::FeatureList::OverrideState override_state;
  } override_info[] = {
      // Overrides for --enable-experimental-web-platform-features.
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(blink::features::kHTMLProcessingInstruction),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(blink::features::kJavaScriptImportText),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(net::features::kCookieSameSiteConsidersRedirectChain),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kDocumentPolicyNegotiation),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kExperimentalContentSecurityPolicyFeatures),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kOriginIsolationHeader),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kEnableCanvas2DLayers),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(blink::features::kCreateImageBitmapOrientationNone),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kCriticalClientHint),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(net::features::kThirdPartyStoragePartitioning),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(network::features::kCookieIndicesHeader),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(features::kPrefetchCookieIndices),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(net::features::kHstsTopLevelNavigationsOnly),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(blink::features::kResponsiveIframes),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalWebPlatformFeatures,
       std::cref(blink::features::kGlobalPrivacyControlTest),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Overrides for --enable-experimental-cookie-features.
      {switches::kEnableExperimentalCookieFeatures,
       std::cref(net::features::kCookieSameSiteConsidersRedirectChain),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalCookieFeatures,
       std::cref(net::features::kSameSiteDefaultChecksMethodRigorously),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalCookieFeatures,
       std::cref(net::features::kEnablePortBoundCookies),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalCookieFeatures,
       std::cref(net::features::kEnableSchemeBoundCookies),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnableExperimentalCookieFeatures,
       std::cref(net::features::kDisallowNonAsciiCookies),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Test behavior for third-party cookie phaseout.
      {network::switches::kTestThirdPartyCookiePhaseout,
       std::cref(net::features::kForceThirdPartyCookieBlocking),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {network::switches::kTestThirdPartyCookiePhaseout,
       std::cref(net::features::kThirdPartyStoragePartitioning),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Overrides for headless
      {::switches::kHeadless, std::cref(blink::features::kPaintHolding),
       base::FeatureList::OVERRIDE_DISABLE_FEATURE},

      // Overrides for disable-ignore-duplicate-navs-for-testing.
      {switches::kDisableIgnoreDuplicateNavsForTesting,
       std::cref(features::kIgnoreDuplicateNavs),
       base::FeatureList::OVERRIDE_DISABLE_FEATURE},

      // Override for --reduce-user-agent-minor-version.
      {switches::kReduceUserAgentMinorVersion,
       std::cref(blink::features::kReduceUserAgentMinorVersion),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Override for --reduce-accept-language.
      {switches::kReduceAcceptLanguage,
       std::cref(network::features::kReduceAcceptLanguage),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Override for --reduce-accept-language-http.
      {switches::kReduceAcceptLanguageHTTP,
       std::cref(network::features::kReduceAcceptLanguageHTTP),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},

      // Override for --privacy-sandbox-ads-apis. See also chrome layer
      // overrides.
      {switches::kEnablePrivacySandboxAdsApis,
       std::cref(features::kPrivacySandboxAdsAPIsOverride),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnablePrivacySandboxAdsApis,
       std::cref(blink::features::kAllowURNsInIframes),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnablePrivacySandboxAdsApis,
       std::cref(network::features::kBrowsingTopics),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
      {switches::kEnablePrivacySandboxAdsApis,
       std::cref(blink::features::kFencedFrames),
       base::FeatureList::OVERRIDE_ENABLE_FEATURE},
  };

  std::vector<base::FeatureList::FeatureOverrideInfo> overrides;
  for (const auto& info : override_info) {
    if (command_line.HasSwitch(info.switch_name))
      overrides.emplace_back(std::make_pair(info.feature, info.override_state));
  }
  return overrides;
}

}  // namespace content
