// Copyright 2018 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/journey/journey_info_json_request.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/journey/proto/batch_get_switcher_journey_from_pageload_request.pb.h"
#include "components/variations/net/variations_http_headers.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.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"

namespace journey {

namespace {

const int k5xxRetries = 2;

std::string GetSerializedJourneyRequest(
    const std::vector<int64_t>& timestamps) {
  BatchGetSwitcherJourneyFromPageloadRequest request;

  for (const auto timestamp : timestamps) {
    request.add_page_timestamp_usec(timestamp);
  }

  return request.SerializeAsString();
}

}  // namespace

JourneyInfoJsonRequest::JourneyInfoJsonRequest(
    const ParseJSONCallback& callback)
    : parse_json_callback_(callback), weak_ptr_factory_(this) {}

JourneyInfoJsonRequest::~JourneyInfoJsonRequest() {}

void JourneyInfoJsonRequest::Start(
    CompletedCallback callback,
    const scoped_refptr<network::SharedURLLoaderFactory>& loader_factory) {
  completed_callback_ = std::move(callback);
  last_response_string_.clear();

  simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
      loader_factory.get(),
      base::BindOnce(&JourneyInfoJsonRequest::OnSimpleURLLoaderComplete,
                     base::Unretained(this)));
}

const std::string& JourneyInfoJsonRequest::GetResponseString() const {
  return last_response_string_;
}

void JourneyInfoJsonRequest::OnSimpleURLLoaderComplete(
    std::unique_ptr<std::string> response_body) {
  DCHECK(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();
  }

  int net_error = simple_url_loader_->NetError();
  simple_url_loader_.reset();

  if (net_error != net::OK) {
    std::move(completed_callback_)
        .Run(nullptr, base::StringPrintf("Network error code: %d", net_error));
  } else if (response_code / 100 != 2) {
    std::move(completed_callback_)
        .Run(nullptr,
             base::StringPrintf("Http response error code: %d", response_code));
  } else {
    last_response_string_ = std::move(*response_body);
    parse_json_callback_.Run(
        last_response_string_,
        base::BindRepeating(&JourneyInfoJsonRequest::OnJsonParsed,
                            weak_ptr_factory_.GetWeakPtr()),
        base::BindRepeating(&JourneyInfoJsonRequest::OnJsonError,
                            weak_ptr_factory_.GetWeakPtr()));
  }
}

void JourneyInfoJsonRequest::OnJsonParsed(std::unique_ptr<base::Value> result) {
  std::move(completed_callback_).Run(std::move(result), std::string());
}

void JourneyInfoJsonRequest::OnJsonError(const std::string& error) {
  DLOG(WARNING) << "Received invalid JSON (" << error
                << "): " << last_response_string_;
  std::move(completed_callback_).Run(nullptr, error);
}

JourneyInfoJsonRequest::Builder::Builder()
    : url_(GURL(
          "https://chrome-memex-dev.appspot.com/api/journey_from_pageload")) {}

JourneyInfoJsonRequest::Builder::~Builder() = default;

std::unique_ptr<JourneyInfoJsonRequest> JourneyInfoJsonRequest::Builder::Build()
    const {
  auto request = std::make_unique<JourneyInfoJsonRequest>(parse_json_callback_);
  request->simple_url_loader_ = BuildSimpleURLLoader();

  return request;
}

JourneyInfoJsonRequest::Builder&
JourneyInfoJsonRequest::Builder::SetAuthentication(
    const std::string& auth_header) {
  DVLOG(0) << "Authorization header " << auth_header;
  auth_header_ = auth_header;
  return *this;
}

JourneyInfoJsonRequest::Builder& JourneyInfoJsonRequest::Builder::SetTimestamps(
    const std::vector<int64_t>& timestamps) {
  body_ = GetSerializedJourneyRequest(timestamps);
  return *this;
}

JourneyInfoJsonRequest::Builder&
JourneyInfoJsonRequest::Builder::SetParseJsonCallback(
    ParseJSONCallback callback) {
  parse_json_callback_ = std::move(callback);
  return *this;
}

net::HttpRequestHeaders
JourneyInfoJsonRequest::Builder::BuildSimpleURLLoaderHeaders() const {
  net::HttpRequestHeaders headers;
  headers.SetHeader("Content-Type", "application/json; charset=UTF-8");
  if (!auth_header_.empty()) {
    headers.SetHeader("Authorization", auth_header_);
  }
  return headers;
}

std::unique_ptr<network::SimpleURLLoader>
JourneyInfoJsonRequest::Builder::BuildSimpleURLLoader() const {
  // TODO(meiliang): update the policy section with correct setting and
  // chrome_policy
  net::NetworkTrafficAnnotationTag traffic_annotation = NO_TRAFFIC_ANNOTATION_YET;

  auto resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = GURL(url_);
  resource_request->load_flags =
      net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES;
  resource_request->headers = BuildSimpleURLLoaderHeaders();
  variations::AppendVariationsHeader(url_, variations::InIncognito::kNo,
                                     variations::SignedIn::kNo,
                                     resource_request.get());
  resource_request->method = "POST";

  auto simple_loader = network::SimpleURLLoader::Create(
      std::move(resource_request), traffic_annotation);
  simple_loader->SetAllowHttpErrorResults(true);
  simple_loader->AttachStringForUpload(body_,
                                       "application/json; charset=UTF-8");
  simple_loader->SetRetryOptions(
      k5xxRetries, network::SimpleURLLoader::RetryMode::RETRY_ON_5XX);

  return simple_loader;
}

}  // namespace journey
