// 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.

#ifndef COBALT_UPDATER_NETWORK_FETCHER_H_
#define COBALT_UPDATER_NETWORK_FETCHER_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "cobalt/network/network_module.h"
#include "components/update_client/network.h"
#include "net/url_request/url_fetcher_delegate.h"

namespace base {

class FilePath;
class SingleThreadTaskRunner;

}  // namespace base

namespace cobalt {
namespace updater {

typedef enum UrlFetcherType {
  kUrlFetcherTypePostRequest,
  kUrlFetcherTypeDownloadToFile,
} UrlFetcherType;

class NetworkFetcher : public update_client::NetworkFetcher,
                       public net::URLFetcherDelegate {
 public:
  using ResponseStartedCallback =
      update_client::NetworkFetcher::ResponseStartedCallback;
  using ProgressCallback = update_client::NetworkFetcher::ProgressCallback;
  using PostRequestCompleteCallback =
      update_client::NetworkFetcher::PostRequestCompleteCallback;
  using DownloadToFileCompleteCallback =
      update_client::NetworkFetcher::DownloadToFileCompleteCallback;

  explicit NetworkFetcher(const network::NetworkModule* network_module);
  ~NetworkFetcher() override;

  // update_client::NetworkFetcher interface.
  void 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) override;
  void DownloadToFile(const GURL& url, const base::FilePath& file_path,
                      ResponseStartedCallback response_started_callback,
                      ProgressCallback progress_callback,
                      DownloadToFileCompleteCallback
                          download_to_file_complete_callback) override;
  void Cancel() override;

  // net::URLFetcherDelegate interface.
  void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
  void OnURLFetchComplete(const net::URLFetcher* source) override;
  void OnURLFetchDownloadProgress(const net::URLFetcher* source,
                                  int64_t current, int64_t total,
                                  int64_t current_network_bytes) override;

 private:
  // Thread checker ensures all calls to the NetworkFetcher are made from the
  // same thread that it is created in.
  THREAD_CHECKER(thread_checker_);

  // Empty struct to ensure the caller of |HandleError()| knows that |this|
  // may have been destroyed and handles it appropriately.
  struct ReturnWrapper {
    void InvalidateThis() {}
  };

  ReturnWrapper HandleError(const std::string& error_message)
      WARN_UNUSED_RESULT;

  void CreateUrlFetcher(const GURL& url,
                        const net::URLFetcher::RequestType request_type);

  void OnPostRequestComplete(const net::URLFetcher* source,
                             const int status_error);
  void OnDownloadToFileComplete(const net::URLFetcher* source,
                                const int status_error);

  static constexpr int kMaxRetriesOnNetworkChange = 3;

  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;

  std::unique_ptr<net::URLFetcher> url_fetcher_;

  UrlFetcherType url_fetcher_type_;

  ResponseStartedCallback response_started_callback_;
  ProgressCallback progress_callback_;
  PostRequestCompleteCallback post_request_complete_callback_;
  DownloadToFileCompleteCallback download_to_file_complete_callback_;

  const network::NetworkModule* network_module_;

  DISALLOW_COPY_AND_ASSIGN(NetworkFetcher);
};

// Network fetcher factory.
class NetworkFetcherFactoryCobalt
    : public update_client::NetworkFetcherFactory {
 public:
  explicit NetworkFetcherFactoryCobalt(network::NetworkModule* network_module);

  std::unique_ptr<update_client::NetworkFetcher> Create() const override;

 protected:
  ~NetworkFetcherFactoryCobalt() override;

 private:
  THREAD_CHECKER(thread_checker_);
  network::NetworkModule* network_module_;

  DISALLOW_COPY_AND_ASSIGN(NetworkFetcherFactoryCobalt);
};

}  // namespace updater
}  // namespace cobalt

#endif  // COBALT_UPDATER_NETWORK_FETCHER_H_
