// Copyright 2020 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/permissions/prediction_service/prediction_service.h"

#include <cmath>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/types/optional_ref.h"
#include "components/permissions/features.h"
#include "components/permissions/prediction_service/prediction_common.h"
#include "components/permissions/prediction_service/prediction_request_features.h"
#include "components/permissions/prediction_service/prediction_service_messages.pb.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "services/network/public/mojom/url_response_head.mojom.h"

namespace {

constexpr base::TimeDelta kURLLookupTimeout = base::Seconds(2);

net::NetworkTrafficAnnotationTag GetTrafficAnnotationTag() {
  return net::DefineNetworkTrafficAnnotation("permission_predictions", R"(
    semantics {
      sender: "Web Permission Perdictions"
      description:
        "A request to the Web Permission Predictions Service. The service will "
        "attempt to predict the likelihood that the user would grant this "
        "permission. Based on this prediction Chrome might decide to present "
        "the user with a different UI; a less intrusive one."
      trigger:
        "A permission prompt is about to be shown to the user, and the user "
        "has opted into Safe Browsing."
      data:
        "User stats helpful for attempting to predict the user's likelihood "
        "of granting the permission: the permission type, the presence of a "
        "user gesture, the user's OS, average deny/grant/ignore/dismiss rates "
        "and total prompts shown, both for the specific permission type and "
        "overall for all permission types."
      destination: GOOGLE_OWNED_SERVICE
    }
    policy {
      cookies_allowed: NO
      setting:
        "This can be disabled by disabling Safe Browsing by going to "
        "Settings and then to the Security sub-menu."
      chrome_policy {
        SafeBrowsingProtectionLevel {
          SafeBrowsingProtectionLevel: 0
        }
      }
    })");
}

}  // namespace

namespace permissions {

PredictionService::PredictionService(
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
    : url_loader_factory_(url_loader_factory) {}
PredictionService::~PredictionService() = default;

void PredictionService::StartLookup(const PredictionRequestFeatures& entity,
                                    LookupRequestCallback request_callback,
                                    LookupResponseCallback response_callback) {
  auto request = GetResourceRequest();
  auto proto_request = GetPredictionRequestProto(entity);
  std::string request_data;

  proto_request->SerializeToString(&request_data);

  SendRequestInternal(std::move(request), request_data, entity,
                      std::move(response_callback));

  if (request_callback)
    std::move(request_callback).Run(std::move(proto_request), std::string());
}

// static
const GURL PredictionService::GetPredictionServiceUrl(
    bool recalculate_for_testing) {
  static base::NoDestructor<GURL> default_prediction_service_url{
      kDefaultPredictionServiceUrl};
  static base::NoDestructor<GURL> command_line_url_override{
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          kDefaultPredictionServiceUrlSwitchKey)};

  // To facilitate tests that want to exercise various url building logic,
  // reinitialize the static variables if this flag is set.
  if (recalculate_for_testing) {
    *command_line_url_override =
        GURL(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            kDefaultPredictionServiceUrlSwitchKey));
  }

  if (command_line_url_override->is_valid())
    return *command_line_url_override;

  return *default_prediction_service_url;
}

std::unique_ptr<network::ResourceRequest>
PredictionService::GetResourceRequest() {
  auto request = std::make_unique<network::ResourceRequest>();

  request->url =
      prediction_service_url_override_.is_empty()
          ? GetPredictionServiceUrl(recalculate_service_url_every_time)
          : prediction_service_url_override_;
  request->load_flags = net::LOAD_DISABLE_CACHE;
  request->method = "POST";
  request->credentials_mode = network::mojom::CredentialsMode::kOmit;

  return request;
}

void PredictionService::SendRequestInternal(
    std::unique_ptr<network::ResourceRequest> request,
    const std::string& request_data,
    const PredictionRequestFeatures& entity,
    LookupResponseCallback response_callback) {
  std::unique_ptr<network::SimpleURLLoader> owned_loader =
      network::SimpleURLLoader::Create(std::move(request),
                                       GetTrafficAnnotationTag());
  owned_loader->AttachStringForUpload(request_data, "application/x-protobuf");

  owned_loader->SetTimeoutDuration(kURLLookupTimeout);
  owned_loader->DownloadToString(
      url_loader_factory_.get(),
      base::BindOnce(&PredictionService::OnURLLoaderComplete,
                     weak_factory_.GetWeakPtr(), entity, owned_loader.get(),
                     base::TimeTicks::Now()),
      network::SimpleURLLoader::kMaxBoundedStringDownloadSize);

  pending_requests_[std::move(owned_loader)] = std::move(response_callback);
}

void PredictionService::OnURLLoaderComplete(
    const PredictionRequestFeatures& entity,
    network::SimpleURLLoader* loader,
    base::TimeTicks request_start_time,
    std::optional<std::string> response_body) {
  for (auto& request : pending_requests_) {
    if (request.first.get() == loader) {
      auto prediction_response =
          CreatePredictionsResponse(loader, response_body);

      if (request.second) {
        std::optional<GeneratePredictionsResponse> response;
        if (prediction_response == nullptr) {
          response = std::nullopt;
        } else {
          response = *prediction_response;
        }
        bool lookup_success = prediction_response != nullptr;
        std::move(request.second)
            .Run(lookup_success, /*Response from cache=*/false, response);
      }

      pending_requests_.erase(request.first);
      return;
    }
  }

  NOTREACHED() << "Unexpected loader callback.";
}

std::unique_ptr<GeneratePredictionsResponse>
PredictionService::CreatePredictionsResponse(
    network::SimpleURLLoader* loader,
    base::optional_ref<std::string> response_body) {
  if (!response_body || loader->NetError() != net::OK ||
      loader->ResponseInfo()->headers->response_code() != net::HTTP_OK) {
    return nullptr;
  }

  auto predictions_response = std::make_unique<GeneratePredictionsResponse>();
  if (!predictions_response->ParseFromString(*response_body)) {
    return nullptr;
  }

  return predictions_response;
}

}  // namespace permissions
