// Copyright 2014 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/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/bind.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_piece.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.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 thread,
// while the BITS specific code runs on a separate thread passed in by the
// client. 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 base::char16 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) {
  return ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr,
                            CLSCTX_INPROC_SERVER,
                            IID_PPV_ARGS(git->GetAddressOf()));
}

// 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.GetAddressOf());
  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.GetAddressOf(), 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,
                             base::string16* local_name,
                             base::string16* remote_name,
                             BG_FILE_PROGRESS* progress) {
  if (!file)
    return E_FAIL;

  HRESULT hr = S_OK;

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

  if (remote_name) {
    ScopedCoMem<base::char16> 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,
                          base::string16* name) {
  ScopedCoMem<base::char16> 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.GetAddressOf());
  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.GetAddressOf());
  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.GetAddressOf(), nullptr) == S_OK &&
        pred(current_job)) {
      base::string16 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::TimeDelta::FromDays(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<base::char16> remote_name;
    if (SUCCEEDED(files[i]->GetRemoteName(&remote_name)) &&
        url == GURL(base::StringPiece16(remote_name)))
      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(__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) {
    base::string16 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(
    std::unique_ptr<CrxDownloader> successor)
    : CrxDownloader(std::move(successor)),
      com_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
          kTaskTraitsBackgroundDownloader)),
      git_cookie_bits_manager_(0),
      git_cookie_job_(0) {}

BackgroundDownloader::~BackgroundDownloader() {
  DCHECK(thread_checker_.CalledOnValidThread());
  timer_.reset();
}

void BackgroundDownloader::StartTimer() {
  timer_.reset(new base::OneShotTimer);
  timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(kJobPollingIntervalSec),
                this, &BackgroundDownloader::OnTimer);
}

void BackgroundDownloader::OnTimer() {
  DCHECK(thread_checker_.CalledOnValidThread());
  com_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::OnDownloading,
                                base::Unretained(this)));
}

void BackgroundDownloader::DoStartDownload(const GURL& url) {
  DCHECK(thread_checker_.CalledOnValidThread());
  com_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::BeginDownload,
                                base::Unretained(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,
                                              base::Unretained(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,
                                              base::Unretained(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,
                                base::Unretained(this), is_handled, result,
                                download_metrics));

  // Once the task is posted to the the main thread, this object may be deleted
  // by its owner. It is not safe to access members of this object on this task
  // runner from now on.
}

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

  main_task_runner()->PostTask(
      FROM_HERE, base::BindOnce(&BackgroundDownloader::OnDownloadProgress,
                                base::Unretained(this)));
  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.GetAddressOf());
  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 base::string16 filename(base::SysUTF8ToWide(url.ExtractFileName()));
  HRESULT hr = job->AddFile(base::SysUTF8ToWide(url.spec()).c_str(),
                            tempdir.Append(filename).AsUTF16Unsafe().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::TimeDelta::FromMinutes(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;

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

  // Sanity 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_.GetAddressOf()));
  if (FAILED(hr))
    return hr;

  hr = GetInterfaceFromGit(git, git_cookie_job_,
                           IID_PPV_ARGS(job_.GetAddressOf()));
  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::TimeDelta::FromDays(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
