// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/updater/network_fetcher.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/loader/url_fetcher_string_writer.h"

namespace {

bool IsResponseCodeSuccess(int response_code) {
  // NetworkFetcher only considers success to be if the network request
  // was successful *and* we get a 2xx response back.
  return response_code / 100 == 2;
}

constexpr net::NetworkTrafficAnnotationTag kNetworkTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("cobalt_updater_network_fetcher",
                                        "cobalt_updater_network_fetcher");

// Returns the string value of a header of the server response or an empty
// string if the header is not available. Only the first header is returned
// if multiple instances of the same header are present.
std::string GetStringHeader(const net::HttpResponseHeaders* headers,
                            const char* header_name) {
  if (!headers) {
    return {};
  }

  std::string header_value;
  return headers->EnumerateHeader(nullptr, header_name, &header_value)
             ? header_value
             : std::string{};
}

// Returns the integral value of a header of the server response or -1 if
// if the header is not available or a conversion error has occurred.
int64_t GetInt64Header(const net::HttpResponseHeaders* headers,
                       const char* header_name) {
  if (!headers) {
    return -1;
  }

  return headers->GetInt64HeaderValue(header_name);
}

}  // namespace

namespace cobalt {
namespace updater {

NetworkFetcher::NetworkFetcher(const network::NetworkModule* network_module)
    : network_module_(network_module) {
  LOG(INFO) << "cobalt::updater::NetworkFetcher::NetworkFetcher";
}

NetworkFetcher::~NetworkFetcher() {
  LOG(INFO) << "cobalt::updater::NetworkFetcher::~NetworkFetcher";
}

void NetworkFetcher::PostRequest(
    const GURL& url, const std::string& post_data,
    const base::flat_map<std::string, std::string>& post_additional_headers,
    ResponseStartedCallback response_started_callback,
    ProgressCallback progress_callback,
    PostRequestCompleteCallback post_request_complete_callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  LOG(INFO) << "cobalt::updater::NetworkFetcher::PostRequest";
  LOG(INFO) << "PostRequest url = " << url;
  LOG(INFO) << "PostRequest post_data = " << post_data;

  response_started_callback_ = std::move(response_started_callback);
  progress_callback_ = std::move(progress_callback);
  post_request_complete_callback_ = std::move(post_request_complete_callback);

  CreateUrlFetcher(url, net::URLFetcher::POST);

  std::unique_ptr<loader::URLFetcherStringWriter> download_data_writer(
      new loader::URLFetcherStringWriter());
  url_fetcher_->SaveResponseWithWriter(std::move(download_data_writer));

  for (const auto& header : post_additional_headers) {
    url_fetcher_->AddExtraRequestHeader(header.first + ": " + header.second);
  }

  url_fetcher_->SetUploadData("application/json", post_data);

  url_fetcher_type_ = kUrlFetcherTypePostRequest;

  url_fetcher_->Start();
}

#if defined(IN_MEMORY_UPDATES)
void NetworkFetcher::DownloadToString(
    const GURL& url, std::string* dst,
    ResponseStartedCallback response_started_callback,
    ProgressCallback progress_callback,
    DownloadToStringCompleteCallback download_to_string_complete_callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  LOG(INFO) << "cobalt::updater::NetworkFetcher::DownloadToString";
  LOG(INFO) << "DownloadToString url = " << url;

  CHECK(dst != nullptr);
  dst_str_ = dst;

  response_started_callback_ = std::move(response_started_callback);
  progress_callback_ = std::move(progress_callback);
  download_to_string_complete_callback_ =
      std::move(download_to_string_complete_callback);

  CreateUrlFetcher(url, net::URLFetcher::GET);

  url_fetcher_->SaveResponseToLargeString();

  url_fetcher_type_ = kUrlFetcherTypeDownloadToString;

  url_fetcher_->Start();
}

#else
void NetworkFetcher::DownloadToFile(
    const GURL& url, const base::FilePath& file_path,
    ResponseStartedCallback response_started_callback,
    ProgressCallback progress_callback,
    DownloadToFileCompleteCallback download_to_file_complete_callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  LOG(INFO) << "cobalt::updater::NetworkFetcher::DownloadToFile";
  LOG(INFO) << "DownloadToFile url = " << url;
  LOG(INFO) << "DownloadToFile file_path = " << file_path;

  response_started_callback_ = std::move(response_started_callback);
  progress_callback_ = std::move(progress_callback);
  download_to_file_complete_callback_ =
      std::move(download_to_file_complete_callback);

  CreateUrlFetcher(url, net::URLFetcher::GET);

  url_fetcher_->SaveResponseToFileAtPath(
      file_path, base::SequencedTaskRunnerHandle::Get());

  url_fetcher_type_ = kUrlFetcherTypeDownloadToFile;

  url_fetcher_->Start();
}
#endif

void NetworkFetcher::Cancel() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  LOG(INFO) << "cobalt::updater::NetworkFetcher::Cancel";
  url_fetcher_.reset();
}

void NetworkFetcher::OnURLFetchResponseStarted(const net::URLFetcher* source) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchResponseStarted";
  std::move(response_started_callback_)
      .Run(source->GetURL(), source->GetResponseCode(),
           source->GetResponseHeaders()
               ? source->GetResponseHeaders()->GetContentLength()
               : -1);
}

void NetworkFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchComplete";
  const net::URLRequestStatus& status = source->GetStatus();
  const int response_code = source->GetResponseCode();
  if (url_fetcher_type_ == kUrlFetcherTypePostRequest) {
    OnPostRequestComplete(source, status.error());
#if defined(IN_MEMORY_UPDATES)
  } else if (url_fetcher_type_ == kUrlFetcherTypeDownloadToString) {
    OnDownloadToStringComplete(source, status.error());
  }
#else
  } else if (url_fetcher_type_ == kUrlFetcherTypeDownloadToFile) {
    OnDownloadToFileComplete(source, status.error());
  }
#endif

  if (!status.is_success() || !IsResponseCodeSuccess(response_code)) {
    std::string msg(base::StringPrintf(
        "NetworkFetcher error on %s : %s, response code %d",
        source->GetURL().spec().c_str(),
        net::ErrorToString(status.error()).c_str(), response_code));
    return HandleError(msg).InvalidateThis();
  }
  url_fetcher_.reset();
}

void NetworkFetcher::OnURLFetchDownloadProgress(const net::URLFetcher* source,
                                                int64_t current, int64_t total,
                                                int64_t current_network_bytes) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchDownloadProgress";

  progress_callback_.Run(current);
}

void NetworkFetcher::CreateUrlFetcher(
    const GURL& url, const net::URLFetcher::RequestType request_type) {
  DCHECK(url.SchemeIsHTTPOrHTTPS());
  url_fetcher_ = net::URLFetcher::Create(url, request_type, this,
                                         kNetworkTrafficAnnotation);

  url_fetcher_->SetRequestContext(
      network_module_->url_request_context_getter().get());
  network_module_->AddClientHintHeaders(*url_fetcher_,
                                        network::kCallTypeUpdater);

  // Request mode is kCORSModeOmitCredentials.
  const uint32 kDisableCookiesAndCacheLoadFlags =
      net::LOAD_NORMAL | net::LOAD_DO_NOT_SAVE_COOKIES |
      net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA |
      net::LOAD_DISABLE_CACHE;
  url_fetcher_->SetLoadFlags(kDisableCookiesAndCacheLoadFlags);

  url_fetcher_->SetAutomaticallyRetryOnNetworkChanges(
      kMaxRetriesOnNetworkChange);
}

void NetworkFetcher::OnPostRequestComplete(const net::URLFetcher* source,
                                           const int status_error) {
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnPostRequestComplete";
  std::unique_ptr<std::string> response_body(new std::string);
  auto* download_data_writer =
      base::polymorphic_downcast<loader::URLFetcherStringWriter*>(
          source->GetResponseWriter());
  if (download_data_writer) {
    download_data_writer->GetAndResetData(response_body.get());
  }

  if (response_body->empty()) {
    LOG(ERROR) << "PostRequest got empty response.";
  }

  LOG(INFO) << "OnPostRequestComplete response_body = " << *response_body.get();

  net::HttpResponseHeaders* response_headers = source->GetResponseHeaders();
  std::move(post_request_complete_callback_)
      .Run(std::move(response_body), status_error,
           GetStringHeader(response_headers,
                           update_client::NetworkFetcher::kHeaderEtag),
           GetInt64Header(response_headers,
                          update_client::NetworkFetcher::kHeaderXRetryAfter));
}

#if defined(IN_MEMORY_UPDATES)
void NetworkFetcher::OnDownloadToStringComplete(const net::URLFetcher* source,
                                                const int status_error) {
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnDownloadToStringComplete";

  if (!source->GetResponseAsLargeString(dst_str_)) {
    LOG(ERROR) << "DownloadToString failed to get response from a string";
  }

  std::move(download_to_string_complete_callback_)
      .Run(dst_str_, status_error,
           source->GetResponseHeaders()
               ? source->GetResponseHeaders()->GetContentLength()
               : -1);
}
#else
void NetworkFetcher::OnDownloadToFileComplete(const net::URLFetcher* source,
                                              const int status_error) {
  LOG(INFO) << "cobalt::updater::NetworkFetcher::OnDownloadToFileComplete";
  base::FilePath response_file;
  if (!source->GetResponseAsFilePath(true, &response_file)) {
    LOG(ERROR) << "DownloadToFile failed to get response from a file";
  }
  LOG(INFO) << "OnDownloadToFileComplete response_file = " << response_file;

  std::move(download_to_file_complete_callback_)
      .Run(response_file, status_error,
           source->GetResponseHeaders()
               ? source->GetResponseHeaders()->GetContentLength()
               : -1);
}
#endif

NetworkFetcher::ReturnWrapper NetworkFetcher::HandleError(
    const std::string& message) {
  LOG(ERROR) << "cobalt::updater::NetworkFetcher::HandleError message="
             << message;
  url_fetcher_.reset();
  return ReturnWrapper();
}

NetworkFetcherFactoryCobalt::NetworkFetcherFactoryCobalt(
    network::NetworkModule* network_module)
    : network_module_(network_module) {}

NetworkFetcherFactoryCobalt::~NetworkFetcherFactoryCobalt() = default;

std::unique_ptr<update_client::NetworkFetcher>
NetworkFetcherFactoryCobalt::Create() const {
  return std::make_unique<NetworkFetcher>(network_module_);
}

}  // namespace updater
}  // namespace cobalt
