// Copyright 2017 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 "third_party/blink/renderer/core/feature_policy/dom_feature_policy.h"

#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/feature_policy/feature_policy_parser.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"

namespace blink {

bool FeatureAvailable(const String& feature, ExecutionContext* ec) {
  return GetDefaultFeatureNameMap().Contains(feature) &&
         (!DisabledByOriginTrial(feature, ec)) &&
         (!IsFeatureForMeasurementOnly(GetDefaultFeatureNameMap().at(feature)));
}

DOMFeaturePolicy::DOMFeaturePolicy(ExecutionContext* context)
    : context_(context) {}

bool DOMFeaturePolicy::allowsFeature(ScriptState* script_state,
                                     const String& feature) const {
  ExecutionContext* execution_context =
      script_state ? ExecutionContext::From(script_state) : nullptr;
  UseCounter::Count(execution_context,
                    IsIFramePolicy()
                        ? WebFeature::kFeaturePolicyJSAPIAllowsFeatureIFrame
                        : WebFeature::kFeaturePolicyJSAPIAllowsFeatureDocument);
  if (FeatureAvailable(feature, execution_context)) {
    auto feature_name = GetDefaultFeatureNameMap().at(feature);
    return GetPolicy()->IsFeatureEnabled(feature_name);
  }

  AddWarningForUnrecognizedFeature(feature);
  return false;
}

bool DOMFeaturePolicy::allowsFeature(ScriptState* script_state,
                                     const String& feature,
                                     const String& url) const {
  ExecutionContext* execution_context =
      script_state ? ExecutionContext::From(script_state) : nullptr;
  UseCounter::Count(
      execution_context,
      IsIFramePolicy()
          ? WebFeature::kFeaturePolicyJSAPIAllowsFeatureOriginIFrame
          : WebFeature::kFeaturePolicyJSAPIAllowsFeatureOriginDocument);
  scoped_refptr<const SecurityOrigin> origin =
      SecurityOrigin::CreateFromString(url);
  if (!origin || origin->IsOpaque()) {
    context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
        mojom::blink::ConsoleMessageSource::kOther,
        mojom::blink::ConsoleMessageLevel::kWarning,
        "Invalid origin url for feature '" + feature + "': " + url + "."));
    return false;
  }

  if (!FeatureAvailable(feature, execution_context)) {
    AddWarningForUnrecognizedFeature(feature);
    return false;
  }

  auto feature_name = GetDefaultFeatureNameMap().at(feature);
  return GetPolicy()->IsFeatureEnabledForOrigin(feature_name,
                                                origin->ToUrlOrigin());
}

Vector<String> DOMFeaturePolicy::features(ScriptState* script_state) const {
  ExecutionContext* execution_context =
      script_state ? ExecutionContext::From(script_state) : nullptr;
  UseCounter::Count(execution_context,
                    IsIFramePolicy()
                        ? WebFeature::kFeaturePolicyJSAPIFeaturesIFrame
                        : WebFeature::kFeaturePolicyJSAPIFeaturesDocument);
  return GetAvailableFeatures(execution_context);
}

Vector<String> DOMFeaturePolicy::allowedFeatures(
    ScriptState* script_state) const {
  ExecutionContext* execution_context =
      script_state ? ExecutionContext::From(script_state) : nullptr;
  UseCounter::Count(
      execution_context,
      IsIFramePolicy()
          ? WebFeature::kFeaturePolicyJSAPIAllowedFeaturesIFrame
          : WebFeature::kFeaturePolicyJSAPIAllowedFeaturesDocument);
  Vector<String> allowed_features;
  for (const String& feature : GetAvailableFeatures(execution_context)) {
    auto feature_name = GetDefaultFeatureNameMap().at(feature);
    if (GetPolicy()->IsFeatureEnabled(feature_name))
      allowed_features.push_back(feature);
  }
  return allowed_features;
}

Vector<String> DOMFeaturePolicy::getAllowlistForFeature(
    ScriptState* script_state,
    const String& feature) const {
  ExecutionContext* execution_context =
      script_state ? ExecutionContext::From(script_state) : nullptr;
  UseCounter::Count(execution_context,
                    IsIFramePolicy()
                        ? WebFeature::kFeaturePolicyJSAPIGetAllowlistIFrame
                        : WebFeature::kFeaturePolicyJSAPIGetAllowlistDocument);
  if (FeatureAvailable(feature, execution_context)) {
    auto feature_name = GetDefaultFeatureNameMap().at(feature);

    const FeaturePolicy::Allowlist allowlist =
        GetPolicy()->GetAllowlistForFeature(feature_name);
    const auto& allowed_origins = allowlist.AllowedOrigins();
    if (allowed_origins.empty()) {
      if (allowlist.MatchesAll())
        return Vector<String>({"*"});
    }
    Vector<String> result;
    for (const auto& origin : allowed_origins) {
      result.push_back(WTF::String::FromUTF8(origin.Serialize()));
    }
    return result;
  }

  AddWarningForUnrecognizedFeature(feature);
  return Vector<String>();
}

void DOMFeaturePolicy::AddWarningForUnrecognizedFeature(
    const String& feature) const {
  context_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
      mojom::blink::ConsoleMessageSource::kOther,
      mojom::blink::ConsoleMessageLevel::kWarning,
      "Unrecognized feature: '" + feature + "'."));
}

void DOMFeaturePolicy::Trace(Visitor* visitor) const {
  ScriptWrappable::Trace(visitor);
  visitor->Trace(context_);
}

}  // namespace blink
