// 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();
}

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();
}

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());
  } else if (url_fetcher_type_ == kUrlFetcherTypeDownloadToFile) {
    OnDownloadToFileComplete(source, status.error());
  }

  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());

  // 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));
}

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);
}

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
