// 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 "chrome/browser/supervised_user/kids_management_url_checker_client.h"

#include <utility>

#include "base/callback.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/supervised_user/supervised_user_constants.h"
#include "components/google/core/common/google_util.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_status.h"
#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
#include "services/identity/public/cpp/scope_set.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 "url/url_constants.h"

enum class KidsManagementClassification { kAllowed, kRestricted, kUnknown };

enum class KidsManagementResponseStatus {
  kSuccess = 0,
  kNetworkError = 1,
  kUnexpectedClassificationValue = 2,
  kParsingError = 3,
  kTokenError = 4,
  kHttpError = 5,
  kMaxValue = kHttpError,
};

struct KidsManagementURLCheckerResponse {
 public:
  KidsManagementClassification classification;
  KidsManagementResponseStatus status;

  static KidsManagementURLCheckerResponse ForSuccess(
      KidsManagementClassification classification) {
    return KidsManagementURLCheckerResponse(
        KidsManagementResponseStatus::kSuccess, classification);
  }

  static KidsManagementURLCheckerResponse ForFailure(
      KidsManagementResponseStatus status) {
    return KidsManagementURLCheckerResponse(
        status, KidsManagementClassification::kUnknown);
  }

 private:
  KidsManagementURLCheckerResponse(
      const KidsManagementResponseStatus& status,
      const KidsManagementClassification& classification)
      : classification(classification), status(status) {}
};

namespace {

const char kClassifyUrlApiPath[] =
    "https://kidsmanagement-pa.googleapis.com/kidsmanagement/v1/people/"
    "me:classifyUrl";

const char kKidPermissionScope[] =
    "https://www.googleapis.com/auth/kid.permission";
const char kDataContentType[] = "application/x-www-form-urlencoded";
const char kDataFormat[] = "url=%s&region_code=%s";
// Possible responses from KidsManagement ClassifyUrl RPC allowed and restricted
const char kAllowed[] = "allowed";
const char kRestricted[] = "restricted";

// Builds the POST data for KidsManagement ClassifyURL requests.
std::string BuildRequestData(const GURL& url, const std::string& region_code) {
  std::string query = net::EscapeQueryParamValue(url.spec(), true);
  return base::StringPrintf(kDataFormat, query.c_str(), region_code.c_str());
}

// Parses a KidsManagement API |response| and returns the classification.
// On failure returns classification kUnknown and status with the reason for
// failure.
KidsManagementURLCheckerResponse ParseResponse(const std::string& response) {
  base::Optional<base::Value> optional_value = base::JSONReader::Read(response);
  const base::DictionaryValue* dict = nullptr;
  if (!optional_value || !optional_value.value().GetAsDictionary(&dict)) {
    DLOG(WARNING) << "ParseResponse failed to parse global dictionary";
    return KidsManagementURLCheckerResponse::ForFailure(
        KidsManagementResponseStatus::kParsingError);
  }

  const base::Value* classification_value =
      dict->FindKey("displayClassification");
  if (!classification_value) {
    DLOG(WARNING) << "ParseResponse failed to parse displayClassification";
    return KidsManagementURLCheckerResponse::ForFailure(
        KidsManagementResponseStatus::kParsingError);
  }

  const std::string classification_string = classification_value->GetString();
  if (classification_string == kAllowed) {
    return KidsManagementURLCheckerResponse::ForSuccess(
        KidsManagementClassification::kAllowed);
  } else if (classification_string == kRestricted) {
    return KidsManagementURLCheckerResponse::ForSuccess(
        KidsManagementClassification::kRestricted);
  }
  DLOG(WARNING) << "ParseResponse expected a valid displayClassification";
  return KidsManagementURLCheckerResponse::ForFailure(
      KidsManagementResponseStatus::kUnexpectedClassificationValue);
}

safe_search_api::ClientClassification ToClientClassification(
    const KidsManagementClassification& classification) {
  switch (classification) {
    case KidsManagementClassification::kAllowed:
      return safe_search_api::ClientClassification::kAllowed;
    case KidsManagementClassification::kRestricted:
      return safe_search_api::ClientClassification::kRestricted;
    case KidsManagementClassification::kUnknown:
      return safe_search_api::ClientClassification::kUnknown;
  }
}

}  // namespace

struct KidsManagementURLCheckerClient::Check {
  Check(const GURL& url, ClientCheckCallback callback);
  ~Check();
  Check(Check&&) = default;

  GURL url;
  std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher>
      access_token_fetcher;
  bool access_token_expired;
  std::unique_ptr<network::SimpleURLLoader> simple_url_loader;
  ClientCheckCallback callback;
  base::TimeTicks start_time;
};

KidsManagementURLCheckerClient::Check::Check(const GURL& url,
                                             ClientCheckCallback callback)
    : url(url),
      access_token_expired(false),
      callback(std::move(callback)),
      start_time(base::TimeTicks::Now()) {}

KidsManagementURLCheckerClient::Check::~Check() {
  DCHECK(!callback);
}

KidsManagementURLCheckerClient::KidsManagementURLCheckerClient(
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const std::string& country,
    identity::IdentityManager* identity_manager)
    : url_loader_factory_(std::move(url_loader_factory)),
      traffic_annotation_(
          net::DefineNetworkTrafficAnnotation("kids_management_url_checker", R"(
        semantics {
          sender: "Supervised Users"
          description:
            "Checks whether a given URL (or set of URLs) is considered safe by "
            "Google KidsManagement."
          trigger:
            "If the parent enabled this feature for the child account, this is "
            "sent for every navigation."
          data:
            "The request is authenticated with an OAuth2 access token "
            "identifying the Google account. The URL to be checked."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting:
            "This feature is only used in child accounts and cannot be "
            "disabled by settings. Parent accounts can disable it in the "
            "family dashboard."
          chrome_policy {
            RestrictSigninToPattern {
              policy_options {mode: MANDATORY}
              RestrictSigninToPattern: "*@manageddomain.com"
            }
          }
        })")),
      country_(country),
      identity_manager_(identity_manager) {}

KidsManagementURLCheckerClient::~KidsManagementURLCheckerClient() = default;

void KidsManagementURLCheckerClient::CheckURL(const GURL& url,
                                              ClientCheckCallback callback) {
  checks_in_progress_.push_front(
      std::make_unique<Check>(url, std::move(callback)));

  StartFetching(checks_in_progress_.begin());
}

void KidsManagementURLCheckerClient::StartFetching(CheckList::iterator it) {
  identity::ScopeSet scopes{kKidPermissionScope};
  // It is safe to use Unretained(this) here given that the callback
  // will not be invoked if this object is deleted. Likewise, |it|
  // only comes from |checks_in_progress_|, which are owned by this object
  // too.
  it->get()->access_token_fetcher =
      std::make_unique<identity::PrimaryAccountAccessTokenFetcher>(
          "kids_url_classifier", identity_manager_, scopes,
          base::BindOnce(
              &KidsManagementURLCheckerClient::OnAccessTokenFetchComplete,
              base::Unretained(this), it),
          identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate);
}

void KidsManagementURLCheckerClient::OnAccessTokenFetchComplete(
    CheckList::iterator it,
    GoogleServiceAuthError error,
    identity::AccessTokenInfo token_info) {
  if (error.state() != GoogleServiceAuthError::NONE) {
    DLOG(WARNING) << "Token error: " << error.ToString();

    DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure(
                           KidsManagementResponseStatus::kTokenError));
    return;
  }
  Check* check = it->get();

  DVLOG(1) << "Checking URL " << check->url;
  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(kClassifyUrlApiPath);
  resource_request->method = "POST";
  resource_request->load_flags =
      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
  resource_request->headers.SetHeader(
      net::HttpRequestHeaders::kAuthorization,
      base::StringPrintf(supervised_users::kAuthorizationHeaderFormat,
                         token_info.token.c_str()));
  check->simple_url_loader = network::SimpleURLLoader::Create(
      std::move(resource_request), traffic_annotation_);
  check->simple_url_loader->AttachStringForUpload(
      BuildRequestData(check->url, country_), kDataContentType);

  check->simple_url_loader->DownloadToString(
      url_loader_factory_.get(),
      base::BindOnce(&KidsManagementURLCheckerClient::OnSimpleLoaderComplete,
                     base::Unretained(this), it, token_info),
      /*max_body_size*/ 128);
}

void KidsManagementURLCheckerClient::OnSimpleLoaderComplete(
    CheckList::iterator it,
    identity::AccessTokenInfo token_info,
    std::unique_ptr<std::string> response_body) {
  Check* check = it->get();
  std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
      std::move(check->simple_url_loader);
  int response_code = -1;
  if (simple_url_loader->ResponseInfo() &&
      simple_url_loader->ResponseInfo()->headers) {
    response_code = simple_url_loader->ResponseInfo()->headers->response_code();
  }

  // Handle first HTTP_UNAUTHORIZED response by removing access token and
  // restarting the request from the beginning (fetching access token).
  if (response_code == net::HTTP_UNAUTHORIZED && !check->access_token_expired) {
    DLOG(WARNING) << "Access token expired:\n" << token_info.token;
    check->access_token_expired = true;
    identity::ScopeSet scopes{kKidPermissionScope};
    identity_manager_->RemoveAccessTokenFromCache(
        identity_manager_->GetPrimaryAccountId(), scopes, token_info.token);
    StartFetching(it);
    return;
  }

  int net_error = simple_url_loader->NetError();
  if (net_error != net::OK) {
    DLOG(WARNING) << "Network error " << net_error;
    DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure(
                           KidsManagementResponseStatus::kNetworkError));
    return;
  }

  if (response_code != net::HTTP_OK) {
    DLOG(WARNING) << "HTTP error " << response_code;
    DLOG(WARNING) << "Response: " << response_body.get();
    DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure(
                           KidsManagementResponseStatus::kHttpError));
    return;
  }

  // |response_body| is nullptr only in case of failure
  if (!response_body) {
    DLOG(WARNING) << "URL request failed! Letting through...";
    DispatchResult(it, KidsManagementURLCheckerResponse::ForFailure(
                           KidsManagementResponseStatus::kNetworkError));
    return;
  }

  DispatchResult(it, ParseResponse(*response_body));
}

void KidsManagementURLCheckerClient::DispatchResult(
    CheckList::iterator it,
    KidsManagementURLCheckerResponse response) {
  if (response.status == KidsManagementResponseStatus::kSuccess) {
    UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlSuccessDelay",
                        base::TimeTicks::Now() - it->get()->start_time);
  } else {
    UMA_HISTOGRAM_TIMES("ManagedUsers.KidsManagementClassifyUrlFailureDelay",
                        base::TimeTicks::Now() - it->get()->start_time);
  }

  UMA_HISTOGRAM_ENUMERATION(
      "ManagedUsers.KidsManagementUrlCheckerResponseStatus", response.status);

  safe_search_api::ClientClassification api_classification =
      ToClientClassification(response.classification);
  std::move(it->get()->callback).Run(it->get()->url, api_classification);

  checks_in_progress_.erase(it);
}
