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

#include "components/client_hints/browser/client_hints.h"

#include <cmath>
#include <functional>
#include <string>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "components/client_hints/common/client_hints.h"
#include "components/client_hints/common/switches.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_constraints.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/embedder_support/user_agent_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "services/network/public/cpp/client_hints.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "third_party/blink/public/common/client_hints/enabled_client_hints.h"
#include "third_party/blink/public/common/features.h"

namespace client_hints {

namespace {
base::flat_map<url::Origin, std::vector<network::mojom::WebClientHintsType>>
ParseInitializeClientHintsStorage() {
  auto results =
      base::flat_map<url::Origin,
                     std::vector<network::mojom::WebClientHintsType>>();

  std::string raw_client_hint_json =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kInitializeClientHintsStorage);

  std::optional<base::Value::Dict> maybe_value = base::JSONReader::ReadDict(
      raw_client_hint_json, base::JSON_PARSE_CHROMIUM_EXTENSIONS);

  if (!maybe_value) {
    LOG(WARNING)
        << "The 'initialize-client-hints-storage' switch value could not be "
        << "properly parsed.";
    return {};
  }

  for (auto entry : *maybe_value) {
    url::Origin origin = url::Origin::Create(GURL(entry.first));
    if (origin.opaque() || origin.scheme() != url::kHttpsScheme) {
      LOG(WARNING)
          << "The url '" << entry.first
          << "' cannot be associated to client hints and will be ignored.";
      continue;
    }

    if (!entry.second.is_string()) {
      LOG(WARNING) << "The value associated with the origin \""
                   << origin.Serialize() << "\" could not be recognized as a "
                   << "valid string and will be ignored.";
      continue;
    }

    std::optional<std::vector<network::mojom::WebClientHintsType>>
        maybe_parsed_accept_ch =
            network::ParseClientHintsHeader(entry.second.GetString());

    if (!maybe_parsed_accept_ch) {
      LOG(WARNING) << "Could not parse the following client hint token list: "
                   << entry.second.GetString();
      continue;
    }

    results[origin] = maybe_parsed_accept_ch.value();
  }

  return results;
}

}  // namespace

ClientHints::ClientHints(
    content::BrowserContext* context,
    network::NetworkQualityTracker* network_quality_tracker,
    HostContentSettingsMap* settings_map,
    scoped_refptr<content_settings::CookieSettings> cookie_settings,
    PrefService* pref_service)
    : context_(context),
      network_quality_tracker_(network_quality_tracker),
      settings_map_(settings_map),
      cookie_settings_(cookie_settings),
      pref_service_(pref_service) {
  DCHECK(context_);
  DCHECK(network_quality_tracker_);
  DCHECK(settings_map_);
  DCHECK(cookie_settings_);

  if (!context->IsOffTheRecord() &&
      base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kInitializeClientHintsStorage)) {
    auto command_line_hints = ParseInitializeClientHintsStorage();

    for (const auto& origin_hints_pair : command_line_hints) {
      PersistClientHints(origin_hints_pair.first, nullptr,
                         origin_hints_pair.second);
    }
  }
}

ClientHints::~ClientHints() = default;

network::NetworkQualityTracker* ClientHints::GetNetworkQualityTracker() {
  return network_quality_tracker_;
}

void ClientHints::GetAllowedClientHintsFromSource(
    const url::Origin& origin,
    blink::EnabledClientHints* client_hints) {
  if (network::features::ShouldBlockAcceptClientHintsFor(origin)) {
    return;
  }
  const GURL& url = origin.GetURL();
  if (!network::IsUrlPotentiallyTrustworthy(url)) {
    return;
  }

  client_hints::GetAllowedClientHints(
      settings_map_->GetWebsiteSetting(
          url, GURL(), ContentSettingsType::CLIENT_HINTS, nullptr),
      client_hints);

  for (auto hint : additional_hints_) {
    client_hints->SetIsEnabled(hint, true);
  }
}

bool ClientHints::IsJavaScriptAllowed(const GURL& url,
                                      content::RenderFrameHost* parent_rfh) {
  return settings_map_->GetContentSetting(
             parent_rfh ? parent_rfh->GetOutermostMainFrame()
                              ->GetLastCommittedOrigin()
                              .GetURL()
                        : url,
             url, ContentSettingsType::JAVASCRIPT) != CONTENT_SETTING_BLOCK;
}

blink::UserAgentMetadata ClientHints::GetUserAgentMetadata() {
  return embedder_support::GetUserAgentMetadata();
}

void ClientHints::PersistClientHints(
    const url::Origin& primary_origin,
    content::RenderFrameHost* parent_rfh,
    const std::vector<network::mojom::WebClientHintsType>& client_hints) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const GURL primary_url = primary_origin.GetURL();

  // TODO(tbansal): crbug.com/735518. Consider killing the renderer that sent
  // the malformed IPC.
  if (!primary_url.is_valid() ||
      !network::IsUrlPotentiallyTrustworthy(primary_url)) {
    return;
  }

  if (!IsJavaScriptAllowed(primary_url, parent_rfh)) {
    return;
  }

  DCHECK_LE(
      client_hints.size(),
      static_cast<size_t>(network::mojom::WebClientHintsType::kMaxValue) + 1);

  if (client_hints.size() >
      (static_cast<size_t>(network::mojom::WebClientHintsType::kMaxValue) +
       1)) {
    // Return early if the list does not have the right number of values.
    // Persisting wrong number of values to the disk may cause errors when
    // reading them back in the future.
    return;
  }

  const auto& persistence_started = base::TimeTicks::Now();
  base::Value::List client_hints_list;
  client_hints_list.reserve(client_hints.size());

  for (const auto& entry : client_hints) {
    client_hints_list.Append(static_cast<int>(entry));
  }

  base::Value::Dict client_hints_dictionary;
  client_hints_dictionary.Set(kClientHintsSettingKey,
                              std::move(client_hints_list));

  // TODO(tbansal): crbug.com/735518. Disable updates to client hints settings
  // when cookies are disabled for |primary_origin|.
  content_settings::ContentSettingConstraints constraints;
  constraints.set_session_model(content_settings::mojom::SessionModel::DURABLE);
  settings_map_->SetWebsiteSettingDefaultScope(
      primary_url, GURL(), ContentSettingsType::CLIENT_HINTS,
      base::Value(std::move(client_hints_dictionary)), constraints);
  network::LogClientHintsPersistenceMetrics(persistence_started,
                                            client_hints.size());
}

void ClientHints::SetAdditionalClientHints(
    const std::vector<network::mojom::WebClientHintsType>& hints) {
  additional_hints_ = hints;
}

void ClientHints::ClearAdditionalClientHints() {
  additional_hints_.clear();
}

void ClientHints::SetMostRecentMainFrameViewportSize(
    const gfx::Size& viewport_size) {
  viewport_size_ = viewport_size;
}

gfx::Size ClientHints::GetMostRecentMainFrameViewportSize() {
  return viewport_size_;
}

void ClientHints::ForceEmptyViewportSizeForTesting(
    bool should_force_empty_viewport_size) {
  should_force_empty_viewport_size_ = should_force_empty_viewport_size;
}

bool ClientHints::ShouldForceEmptyViewportSize() {
  return should_force_empty_viewport_size_;
}

}  // namespace client_hints
