// Copyright 2019 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 "components/optimization_guide/hints_processing_util.h"

#include <string>

#include "base/containers/flat_set.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/stringprintf.h"
#include "components/optimization_guide/hint_update_data.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/url_pattern_with_wildcards.h"
#include "url/gurl.h"

namespace optimization_guide {

// The returned string is used to record histograms for the optimization type.
// Also add the string to OptimizationGuide.OptimizationTypes histogram suffix
// in histograms.xml.
std::string GetStringNameForOptimizationType(
    proto::OptimizationType optimization_type) {
  switch (optimization_type) {
    case proto::OptimizationType::TYPE_UNSPECIFIED:
      return "Unspecified";
    case proto::OptimizationType::NOSCRIPT:
      return "NoScript";
    case proto::OptimizationType::RESOURCE_LOADING:
      return "ResourceLoading";
    case proto::OptimizationType::LITE_PAGE_REDIRECT:
      return "LitePageRedirect";
    case proto::OptimizationType::OPTIMIZATION_NONE:
      return "None";
    case proto::OptimizationType::DEFER_ALL_SCRIPT:
      return "DeferAllScript";
  }
  NOTREACHED();
  return std::string();
}

bool IsDisabledPerOptimizationHintExperiment(
    const proto::Optimization& optimization) {
  // First check if optimization depends on an experiment being enabled.
  if (optimization.has_experiment_name() &&
      !optimization.experiment_name().empty() &&
      optimization.experiment_name() !=
          base::GetFieldTrialParamValueByFeature(
              features::kOptimizationHintsExperiments,
              features::kOptimizationHintsExperimentNameParam)) {
    return true;
  }
  // Now check if optimization depends on an experiment not being enabled.
  if (optimization.has_excluded_experiment_name() &&
      !optimization.excluded_experiment_name().empty() &&
      optimization.excluded_experiment_name() ==
          base::GetFieldTrialParamValueByFeature(
              features::kOptimizationHintsExperiments,
              features::kOptimizationHintsExperimentNameParam)) {
    return true;
  }
  return false;
}

const proto::PageHint* FindPageHintForURL(const GURL& gurl,
                                          const proto::Hint* hint) {
  if (!hint) {
    return nullptr;
  }

  for (const auto& page_hint : hint->page_hints()) {
    if (page_hint.page_pattern().empty()) {
      continue;
    }
    URLPatternWithWildcards url_pattern(page_hint.page_pattern());
    if (url_pattern.Matches(gurl.spec())) {
      // Return the first matching page hint.
      return &page_hint;
    }
  }
  return nullptr;
}

std::string HashHostForDictionary(const std::string& host) {
  return base::StringPrintf("%x", base::PersistentHash(host));
}

bool ProcessHints(google::protobuf::RepeatedPtrField<proto::Hint>* hints,
                  optimization_guide::HintUpdateData* hint_update_data) {
  // If there's no update data, then there's nothing to do.
  if (!hint_update_data)
    return false;

  base::flat_set<std::string> seen_host_suffixes;

  bool did_process_hints = false;
  // Process each hint in the the hint configuration. The hints are mutable
  // because once processing is completed on each individual hint, it is moved
  // into the component update data. This eliminates the need to make any
  // additional copies of the hints.
  for (auto& hint : *hints) {
    // We only support host suffixes at the moment. Skip anything else.
    // One |hint| applies to one host URL suffix.
    if (hint.key_representation() != proto::HOST_SUFFIX) {
      continue;
    }

    const std::string& hint_key = hint.key();

    // Validate configuration keys.
    DCHECK(!hint_key.empty());
    if (hint_key.empty()) {
      continue;
    }

    auto seen_host_suffixes_iter = seen_host_suffixes.find(hint_key);
    DCHECK(seen_host_suffixes_iter == seen_host_suffixes.end());
    if (seen_host_suffixes_iter != seen_host_suffixes.end()) {
      DLOG(WARNING) << "Received config with duplicate key";
      continue;
    }
    seen_host_suffixes.insert(hint_key);

    if (!hint.page_hints().empty()) {
      // Now that processing is finished on |hint|, move it into the update
      // data.
      // WARNING: Do not use |hint| after this call. Its contents will no
      // longer be valid.
      hint_update_data->MoveHintIntoUpdateData(std::move(hint));
      did_process_hints = true;
    }
  }

  return did_process_hints;
}

net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
    proto::EffectiveConnectionType proto_ect) {
  switch (proto_ect) {
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_OFFLINE;
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_SLOW_2G;
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G;
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G;
    case proto::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G:
      return net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G;
  }
}

}  // namespace optimization_guide
