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

#ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_

#include <memory>
#include <string>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/active_install_data.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/webstore_data_fetcher_delegate.h"
#include "chrome/browser/extensions/webstore_install_helper.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/common/extensions/webstore_install_result.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace base {
class DictionaryValue;
}

namespace extensions {
class Extension;
class WebstoreDataFetcher;

// A a purely abstract base for concrete classes implementing various types of
// standalone installs:
// 1) Downloads and parses metadata from the webstore.
// 2) Optionally shows an install dialog.
// 3) Starts download once the user confirms (if confirmation was requested).
// 4) Optionally shows a post-install UI.
// Follows the Template Method pattern. Implementing subclasses must override
// the primitive hooks in the corresponding section below.

class WebstoreStandaloneInstaller
    : public base::RefCountedThreadSafe<WebstoreStandaloneInstaller>,
      public WebstoreDataFetcherDelegate,
      public WebstoreInstaller::Delegate,
      public WebstoreInstallHelper::Delegate {
 public:
  // A callback for when the install process completes, successfully or not. If
  // there was a failure, |success| will be false and |error| may contain a
  // developer-readable error message about why it failed.
  using Callback = base::OnceCallback<void(bool success,
                                           const std::string& error,
                                           webstore_install::Result result)>;

  WebstoreStandaloneInstaller(const std::string& webstore_item_id,
                              Profile* profile,
                              Callback callback);
  void BeginInstall();

 protected:
  ~WebstoreStandaloneInstaller() override;

  // Runs the callback; primarily used for running a callback before it is
  // cleared in AbortInstall(). This should only be called once for the lifetime
  // of the class.
  void RunCallback(
      bool success, const std::string& error, webstore_install::Result result);

  // Called when the install should be aborted. The callback is cleared.
  void AbortInstall();

  // Checks InstallTracker and returns true if the same extension is not
  // currently being installed. Registers this install with the InstallTracker.
  bool EnsureUniqueInstall(webstore_install::Result* reason,
                           std::string* error);

  // Called when the install is complete.
  virtual void CompleteInstall(webstore_install::Result result,
                               const std::string& error);

  // Called when the installer should proceed to prompt the user.
  void ProceedWithInstallPrompt();

  // Lazily creates a dummy extension for display from the parsed manifest. This
  // is safe to call from OnManifestParsed() onwards. The manifest may be
  // invalid, thus the caller must check that the return value is not NULL.
  scoped_refptr<const Extension> GetLocalizedExtensionForDisplay();

  // Template Method's hooks to be implemented by subclasses.

  // Called at certain check points of the workflow to decide whether it makes
  // sense to proceed with installation. A requestor can be a website that
  // initiated an inline installation, or a command line option.
  virtual bool CheckRequestorAlive() const = 0;

  // Should a new tab be opened after installation to show the newly installed
  // extension's icon?
  virtual bool ShouldShowPostInstallUI() const = 0;

  // Should pop up an "App installed" bubble after installation?
  virtual bool ShouldShowAppInstalledBubble() const = 0;

  // In the very least this should return a dummy WebContents (required
  // by some calls even when no prompt or other UI is shown). A non-dummy
  // WebContents is required if the prompt returned by CreateInstallPromt()
  // contains a navigable link(s). Returned WebContents should correspond
  // to |profile| passed into the constructor.
  virtual content::WebContents* GetWebContents() const = 0;

  // Should return an installation prompt with desired properties or NULL if
  // no prompt should be shown.
  virtual std::unique_ptr<ExtensionInstallPrompt::Prompt> CreateInstallPrompt()
      const = 0;

  // Will be called after the extension's manifest has been successfully parsed.
  // Subclasses can perform asynchronous checks at this point and call
  // ProceedWithInstallPrompt() to proceed with the install or otherwise call
  // CompleteInstall() with an error code. The default implementation calls
  // ProceedWithInstallPrompt().
  virtual void OnManifestParsed();

  // Returns an install UI to be shown. By default, this returns an install UI
  // that is a transient child of the host window for GetWebContents().
  virtual std::unique_ptr<ExtensionInstallPrompt> CreateInstallUI();

  // Create an approval to pass installation parameters to the CrxInstaller.
  virtual std::unique_ptr<WebstoreInstaller::Approval> CreateApproval() const;

  // Called once the install prompt has finished.
  virtual void OnInstallPromptDone(ExtensionInstallPrompt::Result result);

  // Accessors to be used by subclasses.
  bool show_user_count() const { return show_user_count_; }
  const std::string& localized_user_count() const {
    return localized_user_count_;
  }
  double average_rating() const { return average_rating_; }
  int rating_count() const { return rating_count_; }
  void set_install_source(WebstoreInstaller::InstallSource source) {
    install_source_ = source;
  }
  WebstoreInstaller::InstallSource install_source() const {
    return install_source_;
  }
  Profile* profile() const { return profile_; }
  const std::string& id() const { return id_; }
  const base::DictionaryValue* manifest() const { return manifest_.get(); }
  const Extension* localized_extension_for_display() const {
    return localized_extension_for_display_.get();
  }

 private:
  friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;

  // Several delegate/client interface implementations follow. The normal flow
  // (for successful installs) is:
  //
  // 1. BeginInstall: starts the fetch of data from the webstore
  // 2. OnURLFetchComplete: starts the parsing of data from the webstore
  // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and
  //    fetching of icon data.
  // 4. OnWebstoreParseSuccess: shows the install UI
  // 5. InstallUIProceed: initiates the .crx download/install
  //
  // All flows (whether successful or not) end up in CompleteInstall, which
  // informs our delegate of success/failure.

  // WebstoreDataFetcherDelegate interface implementation.
  void OnWebstoreRequestFailure() override;

  void OnWebstoreResponseParseSuccess(
      std::unique_ptr<base::DictionaryValue> webstore_data) override;

  void OnWebstoreResponseParseFailure(const std::string& error) override;

  // WebstoreInstallHelper::Delegate interface implementation.
  void OnWebstoreParseSuccess(
      const std::string& id,
      const SkBitmap& icon,
      std::unique_ptr<base::DictionaryValue> parsed_manifest) override;
  void OnWebstoreParseFailure(const std::string& id,
                              InstallHelperResultCode result_code,
                              const std::string& error_message) override;

  // WebstoreInstaller::Delegate interface implementation.
  void OnExtensionInstallSuccess(const std::string& id) override;
  void OnExtensionInstallFailure(
      const std::string& id,
      const std::string& error,
      WebstoreInstaller::FailureReason reason) override;

  void ShowInstallUI();
  void OnWebStoreDataFetcherDone();

  // Input configuration.
  std::string id_;
  Callback callback_;
  Profile* profile_;
  WebstoreInstaller::InstallSource install_source_;

  // Installation dialog and its underlying prompt.
  std::unique_ptr<ExtensionInstallPrompt> install_ui_;
  std::unique_ptr<ExtensionInstallPrompt::Prompt> install_prompt_;

  // For fetching webstore JSON data.
  std::unique_ptr<WebstoreDataFetcher> webstore_data_fetcher_;

  // Extracted from the webstore JSON data response.
  std::string localized_name_;
  std::string localized_description_;
  bool show_user_count_;
  std::string localized_user_count_;
  double average_rating_;
  int rating_count_;
  std::unique_ptr<base::DictionaryValue> webstore_data_;
  std::unique_ptr<base::DictionaryValue> manifest_;
  SkBitmap icon_;

  // Active install registered with the InstallTracker.
  std::unique_ptr<ScopedActiveInstall> scoped_active_install_;

  // Created by ShowInstallUI() when a prompt is shown (if
  // the implementor returns a non-NULL in CreateInstallPrompt()).
  scoped_refptr<Extension> localized_extension_for_display_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
