// 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_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_
#define CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_

#include <stdint.h>

#include <map>
#include <set>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/storage_monitor/removable_storage_observer.h"

class Profile;

namespace extensions {
class Extension;
class ExtensionPrefs;
}

namespace user_prefs {
class PrefRegistrySyncable;
}

typedef uint64_t MediaGalleryPrefId;
const MediaGalleryPrefId kInvalidMediaGalleryPrefId = 0;

const char kMediaGalleriesPrefsVersionKey[] = "preferencesVersion";
const char kMediaGalleriesDefaultGalleryTypeKey[] = "defaultGalleryType";

struct MediaGalleryPermission {
  MediaGalleryPrefId pref_id;
  bool has_permission;
};

struct MediaGalleryPrefInfo {
  enum Type {
    kUserAdded,     // Explicitly added by the user.
    kAutoDetected,  // Auto added to the list of galleries.
    kBlackListed,   // Auto added but then removed by the user.
    kScanResult,    // Discovered by a disk scan.
    kRemovedScan,   // Discovered by a disk scan but then removed by the user.
    kInvalidType,
  };

  enum DefaultGalleryType {
    kNotDefault,    // Normal gallery
    kMusicDefault,
    kPicturesDefault,
    kVideosDefault,
  };

  MediaGalleryPrefInfo();
  MediaGalleryPrefInfo(const MediaGalleryPrefInfo& other);
  ~MediaGalleryPrefInfo();

  // The absolute path of the gallery.
  base::FilePath AbsolutePath() const;

  // True if the gallery should not be displayed to the user
  // i.e. kBlackListed || kRemovedScan.
  bool IsBlackListedType() const;

  // The ID that identifies this gallery in this Profile.
  MediaGalleryPrefId pref_id;

  // The user-visible name of this gallery.
  base::string16 display_name;

  // A string which uniquely and persistently identifies the device that the
  // gallery lives on.
  std::string device_id;

  // The root of the gallery, relative to the root of the device.
  base::FilePath path;

  // The type of gallery.
  Type type;

  // The volume label of the volume/device on which the gallery
  // resides. Empty if there is no such label or it is unknown.
  base::string16 volume_label;

  // Vendor name for the volume/device on which the gallery is located.
  // Will be empty if unknown.
  base::string16 vendor_name;

  // Model name for the volume/device on which the gallery is located.
  // Will be empty if unknown.
  base::string16 model_name;

  // The capacity in bytes of the volume/device on which the gallery is
  // located. Will be zero if unknown.
  uint64_t total_size_in_bytes;

  // If the gallery is on a removable device, the time that device was last
  // attached. It is stored in preferences by the base::Time internal value,
  // which is microseconds since the epoch.
  base::Time last_attach_time;

  // Set to true if the volume metadata fields (volume_label, vendor_name,
  // model_name, total_size_in_bytes) were set. False if these fields were
  // never written.
  bool volume_metadata_valid;

  // The following fields are populated with the audio, image, and video file
  // counts from the last scan. For files where it is hard to determine the
  // exact type, the file should be counted in all possible counts.
  int audio_count;
  int image_count;
  int video_count;

  // Which default gallery this corresponds to (or not default at all).
  DefaultGalleryType default_gallery_type;

  // 0 if the display_name is set externally and always used for display.
  // 1 if the display_name is only set externally when it is overriding
  // the name constructed from volume metadata.
  // 2 if the display_name is set in a consistent manner that has resolved
  // the issues in earlier versions.
  // 3 if the default_gallery_type is set (new field for this version).
  int prefs_version;

  // Called by views to provide details for the gallery permission entries.
  base::string16 GetGalleryDisplayName() const;
  base::string16 GetGalleryTooltip() const;
  base::string16 GetGalleryAdditionalDetails() const;

  // Returns true if the gallery is currently a removable device gallery which
  // is now attached, or a fixed storage gallery.
  bool IsGalleryAvailable() const;
};

typedef std::map<MediaGalleryPrefId, MediaGalleryPrefInfo>
    MediaGalleriesPrefInfoMap;
typedef std::set<MediaGalleryPrefId> MediaGalleryPrefIdSet;

// A class to manage the media gallery preferences.  There is one instance per
// user profile. This class lives on the UI thread.
class MediaGalleriesPreferences
    : public KeyedService,
      public storage_monitor::RemovableStorageObserver {
 public:
  class GalleryChangeObserver {
   public:
    // |extension_id| specifies the extension affected by this change.
    // |pref_id| refers to the gallery.
    virtual void OnPermissionAdded(MediaGalleriesPreferences* pref,
                                   const std::string& extension_id,
                                   MediaGalleryPrefId pref_id) {}

    virtual void OnPermissionRemoved(MediaGalleriesPreferences* pref,
                                     const std::string& extension_id,
                                     MediaGalleryPrefId pref_id) {}

    virtual void OnGalleryAdded(MediaGalleriesPreferences* pref,
                                MediaGalleryPrefId pref_id) {}

    virtual void OnGalleryRemoved(MediaGalleriesPreferences* pref,
                                  MediaGalleryPrefId pref_id) {}

    virtual void OnGalleryInfoUpdated(MediaGalleriesPreferences* pref,
                                      MediaGalleryPrefId pref_id) {}

   protected:
    virtual ~GalleryChangeObserver();
  };

  explicit MediaGalleriesPreferences(Profile* profile);
  ~MediaGalleriesPreferences() override;

  // Ensures that the preferences is initialized. The provided callback, if
  // non-null, will be called when initialization is complete. If initialization
  // has already completed, this callback will be invoked in the calling stack.
  // Before the callback is run, other calls may not return the correct results.
  // Should be invoked on the UI thread; callbacks will be run on the UI thread.
  // This call also ensures that the StorageMonitor is initialized.
  // Note for unit tests: This requires an active ScopedTaskEnvironment and
  // EnsureMediaDirectoriesExists instance to complete reliably.
  void EnsureInitialized(base::Closure callback);

  // Return true if the storage monitor has already been initialized.
  bool IsInitialized() const;

  Profile* profile();

  void AddGalleryChangeObserver(GalleryChangeObserver* observer);
  void RemoveGalleryChangeObserver(GalleryChangeObserver* observer);

  // RemovableStorageObserver implementation.
  void OnRemovableStorageAttached(
      const storage_monitor::StorageInfo& info) override;

  // Lookup a media gallery and fill in information about it and return true if
  // it exists. Return false if it does not, filling in default information.
  bool LookUpGalleryByPath(const base::FilePath& path,
                           MediaGalleryPrefInfo* gallery) const;

  MediaGalleryPrefIdSet LookUpGalleriesByDeviceId(
      const std::string& device_id) const;

  // Returns the absolute file path of the gallery specified by the
  // |gallery_id|. Returns an empty file path if the |gallery_id| is invalid.
  // Set |include_unpermitted_galleries| to true to get the file path of the
  // gallery to which this |extension| has no access permission.
  base::FilePath LookUpGalleryPathForExtension(
      MediaGalleryPrefId gallery_id,
      const extensions::Extension* extension,
      bool include_unpermitted_galleries);

  // Teaches the registry about a new gallery. If the gallery is in a
  // blacklisted state, it is unblacklisted. |type| should not be a blacklisted
  // type. Returns the gallery's pref id.
  MediaGalleryPrefId AddGallery(const std::string& device_id,
                                const base::FilePath& relative_path,
                                MediaGalleryPrefInfo::Type type,
                                const base::string16& volume_label,
                                const base::string16& vendor_name,
                                const base::string16& model_name,
                                uint64_t total_size_in_bytes,
                                base::Time last_attach_time,
                                int audio_count,
                                int image_count,
                                int video_count);

  // Teach the registry about a gallery simply from the path. If the gallery is
  // in a blacklisted state, it is unblacklisted. |type| should not be a
  // blacklisted type. Returns the gallery's pref id.
  MediaGalleryPrefId AddGalleryByPath(const base::FilePath& path,
                                      MediaGalleryPrefInfo::Type type);

  // Logically removes the gallery identified by |id| from the store. For
  // auto added or scan result galleries, this means moving them into a
  // blacklisted state, otherwise they may come back when they are detected
  // again.
  void ForgetGalleryById(MediaGalleryPrefId id);

  // Remove the gallery identified by |id| from the store entirely. If it is an
  // auto added or scan result gallery, it could get added again when the
  // location is noticed again.
  void EraseGalleryById(MediaGalleryPrefId id);

  // Returns true if some extension has permission for |id|, which may not be
  // an auto detected type.
  bool NonAutoGalleryHasPermission(MediaGalleryPrefId id) const;

  MediaGalleryPrefIdSet GalleriesForExtension(
      const extensions::Extension& extension);

  // Returns true if the permission changed. Returns false if there was
  // no change.
  bool SetGalleryPermissionForExtension(const extensions::Extension& extension,
                                        MediaGalleryPrefId pref_id,
                                        bool has_permission);

  const MediaGalleriesPrefInfoMap& known_galleries() const;

  // KeyedService implementation:
  void Shutdown() override;

  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Returns true if the media gallery preferences system has ever been used
  // for this profile. To be exact, it checks if a gallery has ever been added
  // (including defaults).
  static bool APIHasBeenUsed(Profile* profile);

 private:
  friend class MediaGalleriesPreferencesTest;
  friend class MediaGalleriesPermissionsTest;

  typedef std::map<std::string /*device id*/, MediaGalleryPrefIdSet>
      DeviceIdPrefIdsMap;

  // Populates the default galleries. Call only on fresh profiles.
  void AddDefaultGalleries();

  void OnStorageMonitorInit(bool api_has_been_used);

  // Builds |known_galleries_| from the persistent store.
  void InitFromPrefs();

  // Adds a new gallery with the given parameters, or updates in-place an
  // existing gallery with the given device_id if one exists.
  // TODO(orenb): Simplify this and reduce the number of parameters.
  MediaGalleryPrefId AddOrUpdateGalleryInternal(
      const std::string& device_id,
      const base::string16& display_name,
      const base::FilePath& relative_path,
      MediaGalleryPrefInfo::Type type,
      const base::string16& volume_label,
      const base::string16& vendor_name,
      const base::string16& model_name,
      uint64_t total_size_in_bytes,
      base::Time last_attach_time,
      bool volume_metadata_valid,
      int audio_count,
      int image_count,
      int video_count,
      int prefs_version,
      MediaGalleryPrefInfo::DefaultGalleryType default_gallery_type);

  void EraseOrBlacklistGalleryById(MediaGalleryPrefId id, bool erase);

  // Updates the default galleries: finds the previously default galleries
  // and updates their device IDs (i.e., their paths) inplace if they have
  // changed.
  void UpdateDefaultGalleriesPaths();

  // Sets permission for the media galleries identified by |gallery_id| for the
  // extension in the given |prefs|. Returns true only if anything changed.
  bool SetGalleryPermissionInPrefs(const std::string& extension_id,
                                   MediaGalleryPrefId gallery_id,
                                   bool has_access);

  // Removes the entry for the media galleries permissions identified by
  // |gallery_id| for the extension in the given |prefs|.
  // Returns true only if anything changed.
  bool UnsetGalleryPermissionInPrefs(const std::string& extension_id,
                                     MediaGalleryPrefId gallery_id);

  // Return all media gallery permissions for the extension in the given
  // |prefs|.
  std::vector<MediaGalleryPermission> GetGalleryPermissionsFromPrefs(
      const std::string& extension_id) const;

  // Remove all the media gallery permissions in |prefs| for the gallery
  // specified by |gallery_id|.
  void RemoveGalleryPermissionsFromPrefs(MediaGalleryPrefId gallery_id);

  // Get the ExtensionPrefs to use; this will be either the ExtensionPrefs
  // object associated with |profile_|, or extension_prefs_for_testing_, if
  // SetExtensionPrefsForTesting() has been called.
  extensions::ExtensionPrefs* GetExtensionPrefs() const;

  // Set the ExtensionPrefs object to be returned by GetExtensionPrefs().
  void SetExtensionPrefsForTesting(extensions::ExtensionPrefs* extension_prefs);

  bool initialized_;
  std::vector<base::Closure> on_initialize_callbacks_;

  // The profile that owns |this|.
  Profile* profile_;

  // The ExtensionPrefs used in a testing environment, where KeyedServices
  // aren't used. This will be NULL unless it is set with
  // SetExtensionPrefsForTesting().
  extensions::ExtensionPrefs* extension_prefs_for_testing_;

  // An in-memory cache of known galleries.
  MediaGalleriesPrefInfoMap known_galleries_;

  // A mapping from device id to the set of gallery pref ids on that device.
  // All pref ids in |device_map_| are also in |known_galleries_|.
  DeviceIdPrefIdsMap device_map_;

  base::ObserverList<GalleryChangeObserver>::Unchecked
      gallery_change_observers_;

  base::WeakPtrFactory<MediaGalleriesPreferences> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(MediaGalleriesPreferences);
};

#endif  // CHROME_BROWSER_MEDIA_GALLERIES_MEDIA_GALLERIES_PREFERENCES_H_
