// 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_BUNDLE_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_

#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/webstore_install_helper.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/host_desktop.h"
#include "extensions/common/extension.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "url/gurl.h"

namespace base {
class DictionaryValue;
}  // namespace base

namespace content {
class WebContents;
}  // namespace content

class Browser;
class Profile;

namespace extensions {

// Manages the installation life cycle for extension bundles.
//
// We install bundles in two steps:
//  1) PromptForApproval: parse manifests and prompt the user
//  2) CompleteInstall: install the CRXs and show confirmation bubble
//
class BundleInstaller : public WebstoreInstallHelper::Delegate,
                        public ExtensionInstallPrompt::Delegate,
                        public WebstoreInstaller::Delegate,
                        public chrome::BrowserListObserver {
 public:
  // Auto approve or cancel the permission prompt.
  static void SetAutoApproveForTesting(bool approve);

  // Represents an individual member of the bundle.
  struct Item {
    // Items are in the PENDING state until they've been installed, or the
    // install has failed or been canceled.
    enum State {
      STATE_PENDING,
      STATE_INSTALLED,
      STATE_FAILED
    };

    Item();
    ~Item();

    // Gets the localized name, formatted for display in the bubble.
    base::string16 GetNameForDisplay() const;

    std::string id;
    std::string manifest;
    std::string localized_name;
    GURL icon_url;
    SkBitmap icon;
    State state;
  };

  enum ApprovalState {
    APPROVED,
    USER_CANCELED,
    APPROVAL_ERROR
  };

  typedef base::Callback<void(ApprovalState)> ApprovalCallback;

  typedef std::vector<Item> ItemList;

  BundleInstaller(Browser* browser,
                  const std::string& localized_name,
                  const SkBitmap& icon,
                  const std::string& authuser,
                  const std::string& delegated_username,
                  const ItemList& items);
  ~BundleInstaller() override;

  // Returns true if the user has approved the bundle's permissions.
  bool approved() const { return approved_; }

  // Returns the browser window associated with the bundle's installation.
  // Can return null if the browser is closed during the installation.
  Browser* browser() { return browser_; }

  // Gets the items in the given |state|.
  ItemList GetItemsWithState(Item::State state) const;

  // Returns whether there is at least one item with the given |state|.
  bool HasItemWithState(Item::State state) const;

  // Returns the number of items with the given |state|.
  size_t CountItemsWithState(Item::State state) const;

  // Parses the extension manifests and then prompts the user to approve their
  // permissions.
  void PromptForApproval(const ApprovalCallback& callback);

  // If the bundle has been approved, this downloads and installs the member
  // extensions. The download process uses the NavigationController of the
  // specified |web_contents|. When complete, we show a confirmation bubble.
  void CompleteInstall(content::WebContents* web_contents,
                       const base::Closure& callback);

  // We change the headings in the install prompt and installed bubble depending
  // on whether the bundle contains apps, extensions or both. This method gets
  // the correct heading for the items in the specified |state|, or an empty
  // string if no items are in the |state|.
  //   STATE_PENDING   - install prompt
  //   STATE_INSTALLED - installed bubble successful installs list
  //   STATE_FAILED    - installed bubble failed installs list
  base::string16 GetHeadingTextFor(Item::State state) const;

 private:
  typedef std::map<std::string, Item> ItemMap;
  typedef std::map<std::string, linked_ptr<base::DictionaryValue> > ManifestMap;

  // Displays the install bubble for |bundle| on |browser|.
  // Note: this is a platform specific implementation.
  static void ShowInstalledBubble(const BundleInstaller* bundle,
                                  Browser* browser);

  // Parses the manifests using WebstoreInstallHelper.
  void ParseManifests();

  // Prompts the user to install the bundle once we have dummy extensions for
  // all the pending items.
  void ShowPromptIfDoneParsing();

  // Prompts the user to install the bundle.
  void ShowPrompt();

  // Displays the installed bubble once all items have installed or failed.
  void ShowInstalledBubbleIfDone();

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

  // ExtensionInstallPrompt::Delegate implementation:
  void InstallUIProceed() override;
  void InstallUIAbort(bool user_initiated) override;

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

  // chrome::BrowserListObserver implementation:
  void OnBrowserRemoved(Browser* browser) override;

  // Holds the Extensions used to generate the permission warnings.
  ExtensionList dummy_extensions_;

  // Holds the parsed manifests, indexed by the extension ids.
  ManifestMap parsed_manifests_;

  // True if the user has approved the bundle.
  bool approved_;

  // Holds the bundle's Items, indexed by their ids.
  ItemMap items_;

  // The browser to show the confirmation bubble for.
  Browser* browser_;

  // The bundle's display name.
  std::string name_;

  // The bundle's icon.
  SkBitmap icon_;

  // The authuser query parameter value which should be used with CRX download
  // requests. May be empty.
  std::string authuser_;

  // The display name of the user for which this install happens, in the case
  // of delegated installs. Empty for regular installs.
  std::string delegated_username_;

  // The desktop type of the browser.
  chrome::HostDesktopType host_desktop_type_;

  // The profile that the bundle should be installed in.
  Profile* profile_;

  // The UI that shows the confirmation prompt.
  scoped_ptr<ExtensionInstallPrompt> install_ui_;

  ApprovalCallback approval_callback_;
  base::Closure install_callback_;

  DISALLOW_COPY_AND_ASSIGN(BundleInstaller);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
