// Copyright 2015 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/action_update_check.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/version.h"
#include "components/update_client/action_update.h"
#include "components/update_client/configurator.h"
#include "components/update_client/update_checker.h"
#include "components/update_client/update_client.h"
#include "components/update_client/utils.h"

using std::string;
using std::vector;

namespace update_client {

namespace {

// Returns true if the |proposed| version is newer than |current| version.
bool IsVersionNewer(const Version& current, const std::string& proposed) {
  Version proposed_ver(proposed);
  return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0;
}

}  // namespace

ActionUpdateCheck::ActionUpdateCheck(
    scoped_ptr<UpdateChecker> update_checker,
    const base::Version& browser_version,
    const std::string& extra_request_parameters)
    : update_checker_(update_checker.Pass()),
      browser_version_(browser_version),
      extra_request_parameters_(extra_request_parameters) {
}

ActionUpdateCheck::~ActionUpdateCheck() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

void ActionUpdateCheck::Run(UpdateContext* update_context, Callback callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  ActionImpl::Run(update_context, callback);

  // Calls out to get the corresponding CrxComponent data for the CRXs in this
  // update context.
  vector<CrxComponent> crx_components;
  update_context_->crx_data_callback.Run(update_context_->ids, &crx_components);

  update_context_->update_items.reserve(crx_components.size());

  for (size_t i = 0; i != crx_components.size(); ++i) {
    scoped_ptr<CrxUpdateItem> item(new CrxUpdateItem);
    const CrxComponent& crx_component = crx_components[i];

    item->id = GetCrxComponentID(crx_component);
    item->component = crx_component;
    item->last_check = base::Time::Now();
    item->crx_urls.clear();
    item->crx_diffurls.clear();
    item->previous_version = crx_component.version;
    item->next_version = Version();
    item->previous_fp = crx_component.fingerprint;
    item->next_fp.clear();
    item->on_demand = update_context->is_foreground;
    item->diff_update_failed = false;
    item->error_category = 0;
    item->error_code = 0;
    item->extra_code1 = 0;
    item->diff_error_category = 0;
    item->diff_error_code = 0;
    item->diff_extra_code1 = 0;
    item->download_metrics.clear();

    update_context_->update_items.push_back(item.get());

    ChangeItemState(item.get(), CrxUpdateItem::State::kChecking);
    ignore_result(item.release());
  }

  update_checker_->CheckForUpdates(
      update_context_->update_items, extra_request_parameters_,
      base::Bind(&ActionUpdateCheck::UpdateCheckComplete,
                 base::Unretained(this)));
}

void ActionUpdateCheck::UpdateCheckComplete(
    const GURL& original_url,
    int error,
    const std::string& error_message,
    const UpdateResponse::Results& results) {
  DCHECK(thread_checker_.CalledOnValidThread());

  VLOG(1) << "Update check completed from: " << original_url.spec();

  if (!error)
    OnUpdateCheckSucceeded(results);
  else
    OnUpdateCheckFailed(error, error_message);
}

void ActionUpdateCheck::OnUpdateCheckSucceeded(
    const UpdateResponse::Results& results) {
  DCHECK(thread_checker_.CalledOnValidThread());
  VLOG(1) << "Update check succeeded.";
  std::vector<UpdateResponse::Result>::const_iterator it;
  for (it = results.list.begin(); it != results.list.end(); ++it) {
    CrxUpdateItem* crx = FindUpdateItemById(it->extension_id);
    if (!crx)
      continue;

    if (crx->state != CrxUpdateItem::State::kChecking) {
      NOTREACHED();
      continue;  // Not updating this CRX now.
    }

    if (it->manifest.version.empty()) {
      // No version means no update available.
      ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
      VLOG(1) << "No update available for CRX: " << crx->id;
      continue;
    }

    if (!IsVersionNewer(crx->component.version, it->manifest.version)) {
      // The CRX is up to date.
      ChangeItemState(crx, CrxUpdateItem::State::kUpToDate);
      VLOG(1) << "Component already up-to-date: " << crx->id;
      continue;
    }

    if (!it->manifest.browser_min_version.empty()) {
      if (IsVersionNewer(browser_version_, it->manifest.browser_min_version)) {
        // The CRX is not compatible with this Chrome version.
        VLOG(1) << "Ignoring incompatible CRX: " << crx->id;
        ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
        continue;
      }
    }

    if (it->manifest.packages.size() != 1) {
      // Assume one and only one package per CRX.
      VLOG(1) << "Ignoring multiple packages for CRX: " << crx->id;
      ChangeItemState(crx, CrxUpdateItem::State::kNoUpdate);
      continue;
    }

    // Parse the members of the result and queue an upgrade for this CRX.
    crx->next_version = Version(it->manifest.version);

    VLOG(1) << "Update found for CRX: " << crx->id;

    const auto& package(it->manifest.packages[0]);
    crx->next_fp = package.fingerprint;

    // Resolve the urls by combining the base urls with the package names.
    for (size_t i = 0; i != it->crx_urls.size(); ++i) {
      const GURL url(it->crx_urls[i].Resolve(package.name));
      if (url.is_valid())
        crx->crx_urls.push_back(url);
    }
    for (size_t i = 0; i != it->crx_diffurls.size(); ++i) {
      const GURL url(it->crx_diffurls[i].Resolve(package.namediff));
      if (url.is_valid())
        crx->crx_diffurls.push_back(url);
    }

    ChangeItemState(crx, CrxUpdateItem::State::kCanUpdate);

    update_context_->queue.push(crx->id);
  }

  // All components that are not included in the update response are
  // considered up to date.
  ChangeAllItemsState(CrxUpdateItem::State::kChecking,
                      CrxUpdateItem::State::kUpToDate);

  if (update_context_->queue.empty()) {
    VLOG(1) << "Update check completed but no update is needed.";
    UpdateComplete(0);
    return;
  }

  // Starts the execution flow of updating the CRXs in this context.
  UpdateCrx();
}

void ActionUpdateCheck::OnUpdateCheckFailed(int error,
                                            const std::string& error_message) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(error);

  VLOG(1) << "Update check failed." << error;

  ChangeAllItemsState(CrxUpdateItem::State::kChecking,
                      CrxUpdateItem::State::kNoUpdate);

  UpdateComplete(error);
}

}  // namespace update_client
