// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/update_client/background_downloader_win.h"

#include <objbase.h>
#include <winerror.h>

#include <stddef.h>
#include <stdint.h>
#include <functional>
#include <iomanip>
#include <limits>
#include <memory>
#include <utility>
#include <vector>

#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_piece.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_thread_priority.h"
#include "base/win/atl.h"
#include "base/win/scoped_co_mem.h"
#include "components/update_client/task_traits.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
#include "url/gurl.h"

using Microsoft::WRL::ComPtr;
using base::win::ScopedCoMem;

// The class BackgroundDownloader in this module is an adapter between
// the CrxDownloader interface and the BITS service interfaces.
// The interface exposed on the CrxDownloader code runs on the main sequence,
// while the BITS specific code runs in a separate sequence bound to a
// COM apartment. For every url to download, a BITS job is created, unless
// there is already an existing job for that url, in which case, the downloader
// connects to it. Once a job is associated with the url, the code looks for
// changes in the BITS job state. The checks are triggered by a timer.
// The BITS job contains just one file to download. There could only be one
// download in progress at a time. If Chrome closes down before the download is
// complete, the BITS job remains active and finishes in the background, without
// any intervention. The job can be completed next time the code runs, if the
// file is still needed, otherwise it will be cleaned up on a periodic basis.
//
// To list the BITS jobs for a user, use the |bitsadmin| tool. The command line
// to do that is: "bitsadmin /list /verbose". Another useful command is
// "bitsadmin /info" and provide the job id returned by the previous /list
// command.
//
// Ignoring the suspend/resume issues since this code is not using them, the
// job state machine implemented by BITS is something like this:
//
//  Suspended--->Queued--->Connecting---->Transferring--->Transferred
//       |          ^         |                 |               |
//       |          |         V                 V               | (complete)
//       +----------|---------+-----------------+-----+         V
//                  |         |                 |     |    Acknowledged
//                  |         V                 V     |
//                  |  Transient Error------->Error   |
//                  |         |                 |     |(cancel)
//                  |         +-------+---------+--->-+
//                  |                 V               |
//                  |   (resume)      |               |
//                  +------<----------+               +---->Cancelled
//
// The job is created in the "suspended" state. Once |Resume| is called,
// BITS queues up the job, then tries to connect, begins transferring the
// job bytes, and moves the job to the "transferred state, after the job files
// have been transferred. When calling |Complete| for a job, the job files are
// made available to the caller, and the job is moved to the "acknowledged"
// state.
// At any point, the job can be cancelled, in which case, the job is moved
// to the "cancelled state" and the job object is removed from the BITS queue.
// Along the way, the job can encounter recoverable and non-recoverable errors.
// BITS moves the job to "transient error" or "error", depending on which kind
// of error has occured.
// If  the job has reached the "transient error" state, BITS retries the
// job after a certain programmable delay. If the job can't be completed in a
// certain time interval, BITS stops retrying and errors the job out. This time
// interval is also programmable.
// If the job is in either of the error states, the job parameters can be
// adjusted to handle the error, after which the job can be resumed, and the
// whole cycle starts again.
// Jobs that are not touched in 90 days (or a value set by group policy) are
// automatically disposed off by BITS. This concludes the brief description of
// a job lifetime, according to BITS.
//
// In addition to how BITS is managing the life time of the job, there are a
// couple of special cases defined by the BackgroundDownloader.
// First, if the job encounters any of the 5xx HTTP responses, the job is
// not retried, in order to avoid DDOS-ing the servers.
// Second, there is a simple mechanism to detect stuck jobs, and allow the rest
// of the code to move on to trying other urls or trying other components.
// Last, after completing a job, irrespective of the outcome, the jobs older
// than a week are proactively cleaned up.

namespace update_client {

namespace {

// All jobs created by this module have a specific description so they can
// be found at run-time or by using system administration tools.
const wchar_t kJobName[] = L"Chrome Component Updater";

// How often the code looks for changes in the BITS job state.
const int kJobPollingIntervalSec = 4;

// How long BITS waits before retrying a job after the job encountered
// a transient error. If this value is not set, the BITS default is 10 minutes.
const int kMinimumRetryDelayMin = 1;

// How long to wait for stuck jobs. Stuck jobs could be queued for too long,
// have trouble connecting, could be suspended for any reason, or they have
// encountered some transient error.
const int kJobStuckTimeoutMin = 15;

// How long BITS waits before giving up on a job that could not be completed
// since the job has encountered its first transient error. If this value is
// not set, the BITS default is 14 days.
const int kSetNoProgressTimeoutDays = 1;

// How often the jobs which were started but not completed for any reason
// are cleaned up. Reasons for jobs to be left behind include browser restarts,
// system restarts, etc. Also, the check to purge stale jobs only happens
// at most once a day. If the job clean up code is not running, the BITS
// default policy is to cancel jobs after 90 days of inactivity.
const int kPurgeStaleJobsAfterDays = 3;
const int kPurgeStaleJobsIntervalBetweenChecksDays = 1;

// Number of maximum BITS jobs this downloader can create and queue up.
const int kMaxQueuedJobs = 10;

// Retrieves the singleton instance of GIT for this process.
HRESULT GetGit(ComPtr<IGlobalInterfaceTable>* git) {
  // Mitigate the issues caused by loading DLLs on a background thread
  // (http://crbug/973868).
  SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
  return ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr,
                            CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&(*git)));
}

// Retrieves an interface pointer from the process GIT for a given |cookie|.
HRESULT GetInterfaceFromGit(const ComPtr<IGlobalInterfaceTable>& git,
                            DWORD cookie,
                            REFIID riid,
                            void** ppv) {
  return git->GetInterfaceFromGlobal(cookie, riid, ppv);
}

// Registers an interface pointer in GIT and returns its corresponding |cookie|.
template <typename T>
HRESULT RegisterInterfaceInGit(const ComPtr<IGlobalInterfaceTable>& git,
                               const ComPtr<T>& p,
                               DWORD* cookie) {
  return git->RegisterInterfaceInGlobal(p.Get(), __uuidof(T), cookie);
}

// Returns the status code from a given BITS error.
int GetHttpStatusFromBitsError(HRESULT error) {
  // BITS errors are defined in bitsmsg.h. Although not documented, it is
  // clear that all errors corresponding to http status code have the high
  // word equal to 0x8019 and the low word equal to the http status code.
  const int kHttpStatusFirst = 100;  // Continue.
  const int kHttpStatusLast = 505;   // Version not supported.
  bool is_valid = HIWORD(error) == 0x8019 &&
                  LOWORD(error) >= kHttpStatusFirst &&
                  LOWORD(error) <= kHttpStatusLast;
  return is_valid ? LOWORD(error) : 0;
}

// Returns the files in a BITS job.
HRESULT GetFilesInJob(const ComPtr<IBackgroundCopyJob>& job,
                      std::vector<ComPtr<IBackgroundCopyFile>>* files) {
  ComPtr<IEnumBackgroundCopyFiles> enum_files;
  HRESULT hr = job->EnumFiles(&enum_files);
  if (FAILED(hr))
    return hr;

  ULONG num_files = 0;
  hr = enum_files->GetCount(&num_files);
  if (FAILED(hr))
    return hr;

  for (ULONG i = 0; i != num_files; ++i) {
    ComPtr<IBackgroundCopyFile> file;
    if (enum_files->Next(1, &file, nullptr) == S_OK && file.Get())
      files->push_back(file);
  }

  return S_OK;
}

// Returns the file name, the url, and some per-file progress information.
// The function out parameters can be NULL if that data is not requested.
HRESULT GetJobFileProperties(const ComPtr<IBackgroundCopyFile>& file,
                             std::wstring* local_name,
                             std::wstring* remote_name,
                             BG_FILE_PROGRESS* progress) {
  if (!file)
    return E_FAIL;

  HRESULT hr = S_OK;

  if (local_name) {
    ScopedCoMem<wchar_t> name;
    hr = file->GetLocalName(&name);
    if (FAILED(hr))
      return hr;
    local_name->assign(name);
  }

  if (remote_name) {
    ScopedCoMem<wchar_t> name;
    hr = file->GetRemoteName(&name);
    if (FAILED(hr))
      return hr;
    remote_name->assign(name);
  }

  if (progress) {
    BG_FILE_PROGRESS bg_file_progress = {};
    hr = file->GetProgress(&bg_file_progress);
    if (FAILED(hr))
      return hr;
    *progress = bg_file_progress;
  }

  return hr;
}

// Returns the number of bytes downloaded and bytes to download for all files
// in the job. If the values are not known or if an error has occurred,
// a value of -1 is reported.
HRESULT GetJobByteCount(const ComPtr<IBackgroundCopyJob>& job,
                        int64_t* downloaded_bytes,
                        int64_t* total_bytes) {
  *downloaded_bytes = -1;
  *total_bytes = -1;

  if (!job)
    return E_FAIL;

  BG_JOB_PROGRESS job_progress = {};
  HRESULT hr = job->GetProgress(&job_progress);
  if (FAILED(hr))
    return hr;

  const uint64_t kMaxNumBytes =
      static_cast<uint64_t>(std::numeric_limits<int64_t>::max());
  if (job_progress.BytesTransferred <= kMaxNumBytes)
    *downloaded_bytes = job_progress.BytesTransferred;

  if (job_progress.BytesTotal <= kMaxNumBytes &&
      job_progress.BytesTotal != BG_SIZE_UNKNOWN)
    *total_bytes = job_progress.BytesTotal;

  return S_OK;
}

HRESULT GetJobDisplayName(const ComPtr<IBackgroundCopyJob>& job,
                          std::wstring* name) {
  ScopedCoMem<wchar_t> local_name;
  const HRESULT hr = job->GetDisplayName(&local_name);
  if (FAILED(hr))
    return hr;
  *name = local_name.get();
  return S_OK;
}

// Returns the job error code in |error_code| if the job is in the transient
// or the final error state. Otherwise, the job error is not available and
// the function fails.
HRESULT GetJobError(const ComPtr<IBackgroundCopyJob>& job,
                    HRESULT* error_code_out) {
  *error_code_out = S_OK;
  ComPtr<IBackgroundCopyError> copy_error;
  HRESULT hr = job->GetError(&copy_error);
  if (FAILED(hr))
    return hr;

  BG_ERROR_CONTEXT error_context = BG_ERROR_CONTEXT_NONE;
  HRESULT error_code = S_OK;
  hr = copy_error->GetError(&error_context, &error_code);
  if (FAILED(hr))
    return hr;

  *error_code_out = FAILED(error_code) ? error_code : E_FAIL;
  return S_OK;
}

// Finds the component updater jobs matching the given predicate.
// Returns S_OK if the function has found at least one job, returns S_FALSE if
// no job was found, and it returns an error otherwise.
template <class Predicate>
HRESULT FindBitsJobIf(Predicate pred,
                      const ComPtr<IBackgroundCopyManager>& bits_manager,
                      std::vector<ComPtr<IBackgroundCopyJob>>* jobs) {
  ComPtr<IEnumBackgroundCopyJobs> enum_jobs;
  HRESULT hr = bits_manager->EnumJobs(0, &enum_jobs);
  if (FAILED(hr))
    return hr;

  ULONG job_count = 0;
  hr = enum_jobs->GetCount(&job_count);
  if (FAILED(hr))
    return hr;

  // Iterate over jobs, run the predicate, and select the job only if
  // the job description matches the component updater jobs.
  for (ULONG i = 0; i != job_count; ++i) {
    ComPtr<IBackgroundCopyJob> current_job;
    if (enum_jobs->Next(1, &current_job, nullptr) == S_OK &&
        pred(current_job)) {
      std::wstring job_name;
      hr = GetJobDisplayName(current_job, &job_name);
      if (job_name.compare(kJobName) == 0)
        jobs->push_back(current_job);
    }
  }

  return jobs->empty() ? S_FALSE : S_OK;
}

bool JobCreationOlderThanDaysPredicate(ComPtr<IBackgroundCopyJob> job,
                                       int num_days) {
  BG_JOB_TIMES times = {};
  HRESULT hr = job->GetTimes(&times);
  if (FAILED(hr))
    return false;

  const base::TimeDelta time_delta(base::Days(num_days));
  const base::Time creation_time(base::Time::FromFileTime(times.CreationTime));

  return creation_time + time_delta < base::Time::Now();
}

bool JobFileUrlEqualPredicate(ComPtr<IBackgroundCopyJob> job, const GURL& url) {
  std::vector<ComPtr<IBackgroundCopyFile>> files;
  HRESULT hr = GetFilesInJob(job, &files);
  if (FAILED(hr))
    return false;

  for (size_t i = 0; i != files.size(); ++i) {
    ScopedCoMem<wchar_t> remote_name;
    if (SUCCEEDED(files[i]->GetRemoteName(&remote_name)) &&
        url == GURL(base::SysWideToUTF8(remote_name.get())))
      return true;
  }

  return false;
}

// Creates an instance of the BITS manager.
HRESULT CreateBitsManager(ComPtr<IBackgroundCopyManager>* bits_manager) {
  ComPtr<IBackgroundCopyManager> local_bits_manager;
  HRESULT hr;
  {
    // CoCreateInstance may acquire the loader lock to load a library. Doing it
    // at background priority can cause a priority inversion with the main
    // thread, perceived as a hang by the user.
    // SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY() mitigates this problem
    // by boosting the thread's priority. See crbug.com/1295941.
    SCOPED_MAY_LOAD_LIBRARY_AT_BACKGROUND_PRIORITY();
    hr = ::CoCreateInstance(__uuidof(BackgroundCopyManager), nullptr,
                            CLSCTX_ALL, IID_PPV_ARGS(&local_bits_manager));
  }

  if (FAILED(hr)) {
    return hr;
  }
  *bits_manager = local_bits_manager;
  return S_OK;
}

void CleanupJob(const ComPtr<IBackgroundCopyJob>& job) {
  if (!job)
    return;

  // Get the file paths associated with this job before canceling the job.
  // Canceling the job removes it from the BITS queue right away. It appears
  // that it is still possible to query for the properties of the job after
  // the job has been canceled. It seems safer though to get the paths first.
  std::vector<ComPtr<IBackgroundCopyFile>> files;
  GetFilesInJob(job, &files);

  std::vector<base::FilePath> paths;
  for (const auto& file : files) {
    std::wstring local_name;
    HRESULT hr = GetJobFileProperties(file, &local_name, nullptr, nullptr);
    if (SUCCEEDED(hr))
      paths.push_back(base::FilePath(local_name));
  }

  job->Cancel();

  for (const auto& path : paths)
    DeleteFileAndEmptyParentDirectory(path);
}

}  // namespace

BackgroundDownloader::BackgroundDownloader(
    scoped_refptr<CrxDownloader> successor)
    : CrxDownloader(std::move(successor)),
      com_task_runner_(base::ThreadPool::CreateCOMSTATaskRunner(
          kTaskTraitsBackgroundDownloader)),
      git_cookie_bits_manager_(0),
      git_cookie_job_(0) {}

BackgroundDownloader::~BackgroundDownloader() = default;

void BackgroundDownloader::StartTimer() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  timer_ = std::make_unique<base::OneShotTimer>();
  timer_->Start(FROM_HERE, base::Seconds(kJobPollingIntervalSec), this,
                &BackgroundDownloader::OnTimer);
}

void BackgroundDownloader::OnTimer() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  timer_ = nullptr;
  com_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::OnDownloading, this));
}

void BackgroundDownloader::DoStartDownload(const GURL& url) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  com_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&BackgroundDownloader::BeginDownload, this, url));
}

// Called one time when this class is asked to do a download.
void BackgroundDownloader::BeginDownload(const GURL& url) {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  download_start_time_ = base::TimeTicks::Now();
  job_stuck_begin_time_ = download_start_time_;

  HRESULT hr = BeginDownloadHelper(url);
  if (FAILED(hr)) {
    EndDownload(hr);
    return;
  }

  VLOG(1) << "Starting BITS download for: " << url.spec();

  ResetInterfacePointers();
  main_task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::StartTimer, this));
}

// Creates or opens an existing BITS job to download the |url|, and handles
// the marshalling of the interfaces in GIT.
HRESULT BackgroundDownloader::BeginDownloadHelper(const GURL& url) {
  ComPtr<IGlobalInterfaceTable> git;
  HRESULT hr = GetGit(&git);
  if (FAILED(hr))
    return hr;

  hr = CreateBitsManager(&bits_manager_);
  if (FAILED(hr))
    return hr;

  hr = QueueBitsJob(url, &job_);
  if (FAILED(hr))
    return hr;

  hr = RegisterInterfaceInGit(git, bits_manager_, &git_cookie_bits_manager_);
  if (FAILED(hr))
    return hr;

  hr = RegisterInterfaceInGit(git, job_, &git_cookie_job_);
  if (FAILED(hr))
    return hr;

  return S_OK;
}

// Called any time the timer fires.
void BackgroundDownloader::OnDownloading() {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  HRESULT hr = UpdateInterfacePointers();
  if (FAILED(hr)) {
    EndDownload(hr);
    return;
  }

  BG_JOB_STATE job_state = BG_JOB_STATE_ERROR;
  hr = job_->GetState(&job_state);
  if (FAILED(hr)) {
    EndDownload(hr);
    return;
  }

  bool is_handled =  false;
  switch (job_state) {
    case BG_JOB_STATE_TRANSFERRED:
      is_handled = OnStateTransferred();
      break;

    case BG_JOB_STATE_ERROR:
      is_handled = OnStateError();
      break;

    case BG_JOB_STATE_CANCELLED:
      is_handled = OnStateCancelled();
      break;

    case BG_JOB_STATE_ACKNOWLEDGED:
      is_handled = OnStateAcknowledged();
      break;

    case BG_JOB_STATE_QUEUED:
    // Fall through.
    case BG_JOB_STATE_CONNECTING:
    // Fall through.
    case BG_JOB_STATE_SUSPENDED:
      is_handled = OnStateQueued();
      break;

    case BG_JOB_STATE_TRANSIENT_ERROR:
      is_handled = OnStateTransientError();
      break;

    case BG_JOB_STATE_TRANSFERRING:
      is_handled = OnStateTransferring();
      break;

    default:
      break;
  }

  if (is_handled)
    return;

  ResetInterfacePointers();
  main_task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::StartTimer, this));
}

// Completes the BITS download, picks up the file path of the response, and
// notifies the CrxDownloader. The function should be called only once.
void BackgroundDownloader::EndDownload(HRESULT error) {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  const base::TimeTicks download_end_time(base::TimeTicks::Now());
  const base::TimeDelta download_time =
      download_end_time >= download_start_time_
          ? download_end_time - download_start_time_
          : base::TimeDelta();

  int64_t downloaded_bytes = -1;
  int64_t total_bytes = -1;
  GetJobByteCount(job_, &downloaded_bytes, &total_bytes);

  if (FAILED(error))
    CleanupJob(job_);

  ClearGit();

  // Consider the url handled if it has been successfully downloaded or a
  // 5xx has been received.
  const bool is_handled =
      SUCCEEDED(error) || IsHttpServerError(GetHttpStatusFromBitsError(error));

  const int error_to_report = SUCCEEDED(error) ? 0 : error;

  DCHECK(static_cast<bool>(error_to_report) == !base::PathExists(response_));

  DownloadMetrics download_metrics;
  download_metrics.url = url();
  download_metrics.downloader = DownloadMetrics::kBits;
  download_metrics.error = error_to_report;
  download_metrics.downloaded_bytes = downloaded_bytes;
  download_metrics.total_bytes = total_bytes;
  download_metrics.download_time_ms = download_time.InMilliseconds();

  Result result;
  result.error = error_to_report;
  if (!result.error)
    result.response = response_;
  main_task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::OnDownloadComplete, this,
                                is_handled, result, download_metrics));
}

// Called when the BITS job has been transferred successfully. Completes the
// BITS job by removing it from the BITS queue and making the download
// available to the caller.
bool BackgroundDownloader::OnStateTransferred() {
  EndDownload(CompleteJob());
  return true;
}

// Called when the job has encountered an error and no further progress can
// be made. Cancels this job and removes it from the BITS queue.
bool BackgroundDownloader::OnStateError() {
  HRESULT error_code = S_OK;
  HRESULT hr = GetJobError(job_, &error_code);
  if (FAILED(hr))
    error_code = hr;

  DCHECK(FAILED(error_code));
  EndDownload(error_code);
  return true;
}

// Called when the download was completed. This notification is not seen
// in the current implementation but provided here as a defensive programming
// measure.
bool BackgroundDownloader::OnStateAcknowledged() {
  EndDownload(E_UNEXPECTED);
  return true;
}

// Called when the download was cancelled. Same as above.
bool BackgroundDownloader::OnStateCancelled() {
  EndDownload(E_UNEXPECTED);
  return true;
}

// Called when the job has encountered a transient error, such as a
// network disconnect, a server error, or some other recoverable error.
bool BackgroundDownloader::OnStateTransientError() {
  // If the job appears to be stuck, handle the transient error as if
  // it were a final error. This causes the job to be cancelled and a specific
  // error be returned, if the error was available.
  if (IsStuck()) {
    return OnStateError();
  }

  // Don't retry at all if the transient error was a 5xx.
  HRESULT error_code = S_OK;
  HRESULT hr = GetJobError(job_, &error_code);
  if (SUCCEEDED(hr) &&
      IsHttpServerError(GetHttpStatusFromBitsError(error_code))) {
    return OnStateError();
  }

  return false;
}

bool BackgroundDownloader::OnStateQueued() {
  if (!IsStuck())
    return false;

  // Terminate the download if the job has not made progress in a while.
  EndDownload(E_ABORT);
  return true;
}

bool BackgroundDownloader::OnStateTransferring() {
  // Resets the baseline for detecting a stuck job since the job is transferring
  // data and it is making progress.
  job_stuck_begin_time_ = base::TimeTicks::Now();

  int64_t downloaded_bytes = -1;
  int64_t total_bytes = -1;
  GetJobByteCount(job_, &downloaded_bytes, &total_bytes);

  main_task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::OnDownloadProgress, this,
                                downloaded_bytes, total_bytes));
  return false;
}

HRESULT BackgroundDownloader::QueueBitsJob(const GURL& url,
                                           ComPtr<IBackgroundCopyJob>* job) {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  size_t num_jobs = std::numeric_limits<size_t>::max();
  HRESULT hr = GetBackgroundDownloaderJobCount(&num_jobs);

  // The metric records a large number if the job count can't be read.
  UMA_HISTOGRAM_COUNTS_100("UpdateClient.BackgroundDownloaderJobs", num_jobs);

  // Remove some old jobs from the BITS queue before creating new jobs.
  CleanupStaleJobs();

  if (FAILED(hr) || num_jobs >= kMaxQueuedJobs)
    return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF,
                        CrxDownloaderError::BITS_TOO_MANY_JOBS);

  ComPtr<IBackgroundCopyJob> local_job;
  hr = CreateOrOpenJob(url, &local_job);
  if (FAILED(hr)) {
    CleanupJob(local_job);
    return hr;
  }

  const bool is_new_job = hr == S_OK;
  UMA_HISTOGRAM_BOOLEAN("UpdateClient.BackgroundDownloaderNewJob", is_new_job);

  hr = local_job->Resume();
  if (FAILED(hr)) {
    CleanupJob(local_job);
    return hr;
  }

  *job = local_job;
  return S_OK;
}

HRESULT BackgroundDownloader::CreateOrOpenJob(const GURL& url,
                                              ComPtr<IBackgroundCopyJob>* job) {
  std::vector<ComPtr<IBackgroundCopyJob>> jobs;
  HRESULT hr = FindBitsJobIf(
      [&url](ComPtr<IBackgroundCopyJob> job) {
        return JobFileUrlEqualPredicate(job, url);
      },
      bits_manager_, &jobs);
  if (SUCCEEDED(hr) && !jobs.empty()) {
    *job = jobs.front();
    return S_FALSE;
  }

  ComPtr<IBackgroundCopyJob> local_job;

  GUID guid = {0};
  hr = bits_manager_->CreateJob(kJobName, BG_JOB_TYPE_DOWNLOAD, &guid,
                                &local_job);
  if (FAILED(hr)) {
    CleanupJob(local_job);
    return hr;
  }

  hr = InitializeNewJob(local_job, url);
  if (FAILED(hr)) {
    CleanupJob(local_job);
    return hr;
  }

  *job = local_job;
  return S_OK;
}

HRESULT BackgroundDownloader::InitializeNewJob(
    const ComPtr<IBackgroundCopyJob>& job,
    const GURL& url) {
  base::FilePath tempdir;
  if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_BITS_"),
                                    &tempdir))
    return E_FAIL;

  const std::wstring filename(base::SysUTF8ToWide(url.ExtractFileName()));
  HRESULT hr = job->AddFile(base::SysUTF8ToWide(url.spec()).c_str(),
                            tempdir.Append(filename).value().c_str());
  if (FAILED(hr))
    return hr;

  hr = job->SetDescription(filename.c_str());
  if (FAILED(hr))
    return hr;

  hr = job->SetPriority(BG_JOB_PRIORITY_NORMAL);
  if (FAILED(hr))
    return hr;

  hr = job->SetMinimumRetryDelay(60 * kMinimumRetryDelayMin);
  if (FAILED(hr))
    return hr;

  const int kSecondsDay = 60 * 60 * 24;
  hr = job->SetNoProgressTimeout(kSecondsDay * kSetNoProgressTimeoutDays);
  if (FAILED(hr))
    return hr;

  return S_OK;
}

bool BackgroundDownloader::IsStuck() {
  const base::TimeDelta job_stuck_timeout(base::Minutes(kJobStuckTimeoutMin));
  return job_stuck_begin_time_ + job_stuck_timeout < base::TimeTicks::Now();
}

HRESULT BackgroundDownloader::CompleteJob() {
  HRESULT hr = job_->Complete();
  if (FAILED(hr) && hr != BG_S_UNABLE_TO_DELETE_FILES)
    return hr;

  std::vector<ComPtr<IBackgroundCopyFile>> files;
  hr = GetFilesInJob(job_, &files);
  if (FAILED(hr))
    return hr;

  if (files.empty())
    return E_UNEXPECTED;

  std::wstring local_name;
  BG_FILE_PROGRESS progress = {0};
  hr = GetJobFileProperties(files.front(), &local_name, nullptr, &progress);
  if (FAILED(hr))
    return hr;

  // Check the post-conditions of a successful download, including the file and
  // job invariants. The byte counts for a job and its file must match as a job
  // only contains one file.
  DCHECK(progress.Completed);
  DCHECK_EQ(progress.BytesTotal, progress.BytesTransferred);

  response_ = base::FilePath(local_name);

  return S_OK;
}

HRESULT BackgroundDownloader::UpdateInterfacePointers() {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  bits_manager_ = nullptr;
  job_ = nullptr;

  ComPtr<IGlobalInterfaceTable> git;
  HRESULT hr = GetGit(&git);
  if (FAILED(hr))
    return hr;

  hr = GetInterfaceFromGit(git, git_cookie_bits_manager_,
                           IID_PPV_ARGS(&bits_manager_));
  if (FAILED(hr))
    return hr;

  hr = GetInterfaceFromGit(git, git_cookie_job_, IID_PPV_ARGS(&job_));
  if (FAILED(hr))
    return hr;

  return S_OK;
}

void BackgroundDownloader::ResetInterfacePointers() {
  job_ = nullptr;
  bits_manager_ = nullptr;
}

HRESULT BackgroundDownloader::ClearGit() {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());

  ResetInterfacePointers();

  ComPtr<IGlobalInterfaceTable> git;
  HRESULT hr = GetGit(&git);
  if (FAILED(hr))
    return hr;

  const DWORD cookies[] = {
      git_cookie_job_, git_cookie_bits_manager_
  };

  for (auto cookie : cookies) {
    // TODO(sorin): check the result of the call, see crbug.com/644857.
    git->RevokeInterfaceFromGlobal(cookie);
  }

  return S_OK;
}

HRESULT BackgroundDownloader::GetBackgroundDownloaderJobCount(
    size_t* num_jobs) {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());
  DCHECK(bits_manager_);

  std::vector<ComPtr<IBackgroundCopyJob>> jobs;
  const HRESULT hr =
      FindBitsJobIf([](const ComPtr<IBackgroundCopyJob>&) { return true; },
                    bits_manager_, &jobs);
  if (FAILED(hr))
    return hr;

  *num_jobs = jobs.size();
  return S_OK;
}

void BackgroundDownloader::CleanupStaleJobs() {
  DCHECK(com_task_runner_->RunsTasksInCurrentSequence());
  DCHECK(bits_manager_);

  static base::Time last_sweep;

  const base::TimeDelta time_delta(
      base::Days(kPurgeStaleJobsIntervalBetweenChecksDays));
  const base::Time current_time(base::Time::Now());
  if (last_sweep + time_delta > current_time)
    return;

  last_sweep = current_time;

  std::vector<ComPtr<IBackgroundCopyJob>> jobs;
  FindBitsJobIf(
      [](ComPtr<IBackgroundCopyJob> job) {
        return JobCreationOlderThanDaysPredicate(job, kPurgeStaleJobsAfterDays);
      },
      bits_manager_, &jobs);

  for (const auto& job : jobs)
    CleanupJob(job);
}

}  // namespace update_client
