// Copyright (c) 2012 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 "chrome/browser/ui/webui/help/version_updater_win.h"

#include "base/memory/weak_ptr.h"
#include "base/task_scheduler/post_task.h"
#include "base/win/win_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/first_run/upgrade_util.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/native_widget_types.h"

VersionUpdaterWin::VersionUpdaterWin(gfx::AcceleratedWidget owner_widget)
    : owner_widget_(owner_widget), weak_factory_(this) {
}

VersionUpdaterWin::~VersionUpdaterWin() {
}

void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback,
                                       const PromoteCallback&) {
  // There is no supported integration with Google Update for Chromium.
  callback_ = callback;

  callback_.Run(CHECKING, 0, std::string(), 0, base::string16());
  DoBeginUpdateCheck(false /* !install_update_if_possible */);
}

void VersionUpdaterWin::OnUpdateCheckComplete(
    const base::string16& new_version) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (new_version.empty()) {
    // Google Update says that no new version is available. Check to see if a
    // restart is needed for a previously-applied update to take effect.
    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
        base::Bind(&upgrade_util::IsUpdatePendingRestart),
        base::Bind(&VersionUpdaterWin::OnPendingRestartCheck,
                   weak_factory_.GetWeakPtr()));
    // Early exit since callback_ will be Run in OnPendingRestartCheck.
    return;
  }

  // Notify the caller that the update is now beginning and initiate it.
  DoBeginUpdateCheck(true /* install_update_if_possible */);
  callback_.Run(UPDATING, 0, std::string(), 0, base::string16());
}

void VersionUpdaterWin::OnUpgradeProgress(int progress,
                                          const base::string16& new_version) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  callback_.Run(UPDATING, progress, std::string(), 0, base::string16());
}

void VersionUpdaterWin::OnUpgradeComplete(const base::string16& new_version) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  callback_.Run(NEARLY_UPDATED, 0, std::string(), 0, base::string16());
}

void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code,
                                const base::string16& html_error_message,
                                const base::string16& new_version) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  base::string16 message;
  Status status = FAILED;

  switch (error_code) {
    case GOOGLE_UPDATE_DISABLED_BY_POLICY:
      status = DISABLED_BY_ADMIN;
      message =
          l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY);
      break;
    case GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY:
      status = DISABLED_BY_ADMIN;
      message =
          l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY_MANUAL);
      break;
    default:
      // html_error_message mentions error_code so don't combine messages.
      if (html_error_message.empty()) {
        message = l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code);
      } else {
        message = l10n_util::GetStringFUTF16(
            IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK, html_error_message);
      }
      break;
  }
  callback_.Run(status, 0, std::string(), 0, message);
}

void VersionUpdaterWin::DoBeginUpdateCheck(bool install_update_if_possible) {
  // Disconnect from any previous attempts to avoid redundant callbacks.
  weak_factory_.InvalidateWeakPtrs();
  BeginUpdateCheck(g_browser_process->GetApplicationLocale(),
                   install_update_if_possible, owner_widget_,
                   weak_factory_.GetWeakPtr());
}

void VersionUpdaterWin::OnPendingRestartCheck(bool is_update_pending_restart) {
  callback_.Run(is_update_pending_restart ? NEARLY_UPDATED : UPDATED, 0,
                std::string(), 0, base::string16());
}

VersionUpdater* VersionUpdater::Create(content::WebContents* web_contents) {
  // Retrieve the HWND for the browser window that is hosting the update check.
  // This will be used as the parent for a UAC prompt, if needed. It's possible
  // this this window will no longer have focus by the time UAC is needed. In
  // that case, the UAC prompt will appear in the taskbar and will require a
  // user click. This is the least surprising thing we can do for the user, and
  // is the intended behavior for Windows applications.
  // It's also possible that the browser window hosting the update check will
  // have been closed by the time the UAC prompt is needed. In this case, the
  // web contents may no longer be hosted in a window, leading either
  // GetTopLevelNativeWindow or GetHost to return null. Passing nullptr to
  // VersionUpdaterWin will then also cause the UAC prompt to appear in the task
  // bar.
  gfx::NativeWindow window = web_contents->GetTopLevelNativeWindow();
  aura::WindowTreeHost* window_tree_host = window ? window->GetHost() : nullptr;
  return new VersionUpdaterWin(
      window_tree_host ? window_tree_host->GetAcceleratedWidget() : nullptr);
}
