// 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 CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_
#define CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_

#include <map>
#include <string>

#include "base/callback_forward.h"
#include "base/containers/hash_tables.h"
#include "base/gtest_prod_util.h"
#include "base/supports_user_data.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"

namespace base {
class FilePath;
class SequencedTaskRunner;
}  // namespace base

namespace content {

class BrowserContext;

// A std::string to StoragePartition map for use with SupportsUserData APIs.
class CONTENT_EXPORT StoragePartitionImplMap
  : public base::SupportsUserData::Data {
 public:
  explicit StoragePartitionImplMap(BrowserContext* browser_context);

  virtual ~StoragePartitionImplMap();

  // This map retains ownership of the returned StoragePartition objects.
  StoragePartitionImpl* Get(const std::string& partition_domain,
                            const std::string& partition_name,
                            bool in_memory);

  // Starts an asynchronous best-effort attempt to delete all on-disk storage
  // related to |site|, avoiding any directories that are known to be in use.
  //
  // |on_gc_required| is called if the AsyncObliterate() call was unable to
  // fully clean the on-disk storage requiring a call to GarbageCollect() on
  // the next browser start.
  void AsyncObliterate(const GURL& site, const base::Closure& on_gc_required);

  // Examines the on-disk storage and removes any entires that are not listed
  // in the |active_paths|, or in use by current entries in the storage
  // partition.
  //
  // The |done| closure is executed on the calling thread when garbage
  // collection is complete.
  void GarbageCollect(scoped_ptr<base::hash_set<base::FilePath> > active_paths,
                      const base::Closure& done);

  void ForEach(const BrowserContext::StoragePartitionCallback& callback);

 private:
  FRIEND_TEST_ALL_PREFIXES(StoragePartitionConfigTest, OperatorLess);
  FRIEND_TEST_ALL_PREFIXES(StoragePartitionImplMapTest, GarbageCollect);

  // Each StoragePartition is uniquely identified by which partition domain
  // it belongs to (such as an app or the browser itself), the user supplied
  // partition name and the bit indicating whether it should be persisted on
  // disk or not. This structure contains those elements and is used as
  // uniqueness key to lookup StoragePartition objects in the global map.
  //
  // TODO(nasko): It is equivalent, though not identical to the same structure
  // that lives in chrome profiles. The difference is that this one has
  // partition_domain and partition_name separate, while the latter one has
  // the path produced by combining the two pieces together.
  // The fix for http://crbug.com/159193 will remove the chrome version.
  struct StoragePartitionConfig {
    const std::string partition_domain;
    const std::string partition_name;
    const bool in_memory;

    StoragePartitionConfig(const std::string& domain,
                               const std::string& partition,
                               const bool& in_memory_only)
      : partition_domain(domain),
        partition_name(partition),
        in_memory(in_memory_only) {}
  };

  // Functor for operator <.
  struct StoragePartitionConfigLess {
    bool operator()(const StoragePartitionConfig& lhs,
                    const StoragePartitionConfig& rhs) const {
      if (lhs.partition_domain != rhs.partition_domain)
        return lhs.partition_domain < rhs.partition_domain;
      else if (lhs.partition_name != rhs.partition_name)
        return lhs.partition_name < rhs.partition_name;
      else if (lhs.in_memory != rhs.in_memory)
        return lhs.in_memory < rhs.in_memory;
      else
        return false;
    }
  };

  typedef std::map<StoragePartitionConfig,
                   StoragePartitionImpl*,
                   StoragePartitionConfigLess>
      PartitionMap;

  // Returns the relative path from the profile's base directory, to the
  // directory that holds all the state for storage contexts in the given
  // |partition_domain| and |partition_name|.
  static base::FilePath GetStoragePartitionPath(
      const std::string& partition_domain,
      const std::string& partition_name);

  // This must always be called *after* |partition| has been added to the
  // partitions_.
  //
  // TODO(ajwong): Is there a way to make it so that Get()'s implementation
  // doesn't need to be aware of this ordering?  Revisit when refactoring
  // ResourceContext and AppCache to respect storage partitions.
  void PostCreateInitialization(StoragePartitionImpl* partition,
                                bool in_memory);

  BrowserContext* browser_context_;  // Not Owned.
  scoped_refptr<base::SequencedTaskRunner> file_access_runner_;
  PartitionMap partitions_;

  // Set to true when the ResourceContext for the associated |browser_context_|
  // is initialized. Can never return to false.
  bool resource_context_initialized_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_STORAGE_PARTITION_MAP_H_
