// Copyright (c) 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.

#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_ASSETS_MANAGER_CHROMEOS_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_ASSETS_MANAGER_CHROMEOS_H_

#include <map>

#include "chrome/browser/extensions/extension_assets_manager.h"

template <typename T> struct DefaultSingletonTraits;
class PrefRegistrySimple;

namespace base {
class DictionaryValue;
class SequencedTaskRunner;
}

namespace extensions {

// Chrome OS specific implementation of assets manager that shares default apps
// between all users on the machine.
class ExtensionAssetsManagerChromeOS : public ExtensionAssetsManager {
 public:
  static ExtensionAssetsManagerChromeOS* GetInstance();

  // A dictionary that maps shared extension IDs to version/paths/users.
  static const char kSharedExtensions[];

  // Name of path attribute in shared extensions map.
  static const char kSharedExtensionPath[];

  // Name of users attribute (list of user emails) in shared extensions map.
  static const char kSharedExtensionUsers[];

  // Register shared assets related preferences.
  static void RegisterPrefs(PrefRegistrySimple* registry);

  // Override from ExtensionAssetsManager.
  virtual void InstallExtension(const Extension* extension,
                                const base::FilePath& unpacked_extension_root,
                                const base::FilePath& local_install_dir,
                                Profile* profile,
                                InstallExtensionCallback callback) OVERRIDE;
  virtual void UninstallExtension(
      const std::string& id,
      Profile* profile,
      const base::FilePath& local_install_dir,
      const base::FilePath& extension_root) OVERRIDE;

  // Return shared install dir.
  static base::FilePath GetSharedInstallDir();

  // Cleans up shared extensions list in preferences and returns list of
  // extension IDs and version paths that are in use in |live_extension_paths|.
  // Files on disk are not removed. Must be called on UI thread.
  // Returns |false| in case of errors.
  static bool CleanUpSharedExtensions(
      std::multimap<std::string, base::FilePath>* live_extension_paths);

  static void SetSharedInstallDirForTesting(const base::FilePath& install_dir);

 private:
  friend struct DefaultSingletonTraits<ExtensionAssetsManagerChromeOS>;

  ExtensionAssetsManagerChromeOS();
  virtual ~ExtensionAssetsManagerChromeOS();

  // Should be called on UI thread to get associated file task runner for
  // the profile.
  static base::SequencedTaskRunner* GetFileTaskRunner(Profile* profile);

  // Return |true| if |extension| can be installed in a shared place for all
  // users on the device.
  static bool CanShareAssets(const Extension* extension);

  // Called on the UI thread to check if a given version of the |extension|
  // already exists at the shared location.
  static void CheckSharedExtension(
      const std::string& id,
      const std::string& version,
      const base::FilePath& unpacked_extension_root,
      const base::FilePath& local_install_dir,
      Profile* profile,
      InstallExtensionCallback callback);

  // Called on task runner thread to install extension to shared location.
  static void InstallSharedExtension(
      const std::string& id,
      const std::string& version,
      const base::FilePath& unpacked_extension_root);

  // Called on UI thread to process shared install result.
  static void InstallSharedExtensionDone(
      const std::string& id,
      const std::string& version,
      const base::FilePath& shared_version_dir);

  // Called on task runner thread to install the extension to local dir call
  // callback with the result.
  static void InstallLocalExtension(
      const std::string& id,
      const std::string& version,
      const base::FilePath& unpacked_extension_root,
      const base::FilePath& local_install_dir,
      InstallExtensionCallback callback);

  // Called on UI thread to mark that shared version is not used.
  static void MarkSharedExtensionUnused(const std::string& id,
                                        Profile* profile);

  // Called on task runner thread to remove shared version.
  static void DeleteSharedVersion(const base::FilePath& shared_version_dir);

  // Clean shared extension with given |id|.
  static bool CleanUpExtension(
      const std::string& id,
      base::DictionaryValue* extension_info,
      std::multimap<std::string, base::FilePath>* live_extension_paths);

  DISALLOW_COPY_AND_ASSIGN(ExtensionAssetsManagerChromeOS);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_ASSETS_MANAGER_CHROMEOS_H_