// Copyright (c) 2013 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 NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_

#include <list>
#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/cache_type.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"

#if defined(OS_ANDROID)
#include "base/android/application_status_listener.h"
#endif

class Pickle;
class PickleIterator;

namespace disk_cache {

class SimpleIndexDelegate;
class SimpleIndexFile;
struct SimpleIndexLoadResult;

class NET_EXPORT_PRIVATE EntryMetadata {
 public:
  EntryMetadata();
  EntryMetadata(base::Time last_used_time, int entry_size);

  base::Time GetLastUsedTime() const;
  void SetLastUsedTime(const base::Time& last_used_time);

  int GetEntrySize() const { return entry_size_; }
  void SetEntrySize(int entry_size) { entry_size_ = entry_size; }

  // Serialize the data into the provided pickle.
  void Serialize(Pickle* pickle) const;
  bool Deserialize(PickleIterator* it);

  static base::TimeDelta GetLowerEpsilonForTimeComparisons() {
    return base::TimeDelta::FromSeconds(1);
  }
  static base::TimeDelta GetUpperEpsilonForTimeComparisons() {
    return base::TimeDelta();
  }

 private:
  friend class SimpleIndexFileTest;

  // There are tens of thousands of instances of EntryMetadata in memory, so the
  // size of each entry matters.  Even when the values used to set these members
  // are originally calculated as >32-bit types, the actual necessary size for
  // each shouldn't exceed 32 bits, so we use 32-bit types here.
  uint32 last_used_time_seconds_since_epoch_;
  int32 entry_size_;  // Storage size in bytes.
};
COMPILE_ASSERT(sizeof(EntryMetadata) == 8, metadata_size);

// This class is not Thread-safe.
class NET_EXPORT_PRIVATE SimpleIndex
    : public base::SupportsWeakPtr<SimpleIndex> {
 public:
  typedef std::vector<uint64> HashList;

  SimpleIndex(const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
              SimpleIndexDelegate* delegate,
              net::CacheType cache_type,
              scoped_ptr<SimpleIndexFile> simple_index_file);

  virtual ~SimpleIndex();

  void Initialize(base::Time cache_mtime);

  bool SetMaxSize(int max_bytes);
  int max_size() const { return max_size_; }

  void Insert(uint64 entry_hash);
  void Remove(uint64 entry_hash);

  // Check whether the index has the entry given the hash of its key.
  bool Has(uint64 entry_hash) const;

  // Update the last used time of the entry with the given key and return true
  // iff the entry exist in the index.
  bool UseIfExists(uint64 entry_hash);

  void WriteToDisk();

  // Update the size (in bytes) of an entry, in the metadata stored in the
  // index. This should be the total disk-file size including all streams of the
  // entry.
  bool UpdateEntrySize(uint64 entry_hash, int entry_size);

  typedef base::hash_map<uint64, EntryMetadata> EntrySet;

  static void InsertInEntrySet(uint64 entry_hash,
                               const EntryMetadata& entry_metadata,
                               EntrySet* entry_set);

  // Executes the |callback| when the index is ready. Allows multiple callbacks.
  int ExecuteWhenReady(const net::CompletionCallback& callback);

  // Returns entries from the index that have last accessed time matching the
  // range between |initial_time| and |end_time| where open intervals are
  // possible according to the definition given in |DoomEntriesBetween()| in the
  // disk cache backend interface.
  scoped_ptr<HashList> GetEntriesBetween(const base::Time initial_time,
                                         const base::Time end_time);

  // Returns the list of all entries key hash.
  scoped_ptr<HashList> GetAllHashes();

  // Returns number of indexed entries.
  int32 GetEntryCount() const;

  // Returns whether the index has been initialized yet.
  bool initialized() const { return initialized_; }

 private:
  friend class SimpleIndexTest;
  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge);
  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteQueued);
  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWriteExecuted);
  FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, DiskWritePostponed);

  void StartEvictionIfNeeded();
  void EvictionDone(int result);

  void PostponeWritingToDisk();

  void UpdateEntryIteratorSize(EntrySet::iterator* it, int entry_size);

  // Must run on IO Thread.
  void MergeInitializingSet(scoped_ptr<SimpleIndexLoadResult> load_result);

#if defined(OS_ANDROID)
  void OnApplicationStateChange(base::android::ApplicationState state);

  scoped_ptr<base::android::ApplicationStatusListener> app_status_listener_;
#endif

  // The owner of |this| must ensure the |delegate_| outlives |this|.
  SimpleIndexDelegate* delegate_;

  EntrySet entries_set_;

  const net::CacheType cache_type_;
  uint64 cache_size_;  // Total cache storage size in bytes.
  uint64 max_size_;
  uint64 high_watermark_;
  uint64 low_watermark_;
  bool eviction_in_progress_;
  base::TimeTicks eviction_start_time_;

  // This stores all the entry_hash of entries that are removed during
  // initialization.
  base::hash_set<uint64> removed_entries_;
  bool initialized_;

  scoped_ptr<SimpleIndexFile> index_file_;

  scoped_refptr<base::SingleThreadTaskRunner> io_thread_;

  // All nonstatic SimpleEntryImpl methods should always be called on the IO
  // thread, in all cases. |io_thread_checker_| documents and enforces this.
  base::ThreadChecker io_thread_checker_;

  // Timestamp of the last time we wrote the index to disk.
  // PostponeWritingToDisk() may give up postponing and allow the write if it
  // has been a while since last time we wrote.
  base::TimeTicks last_write_to_disk_;

  base::OneShotTimer<SimpleIndex> write_to_disk_timer_;
  base::Closure write_to_disk_cb_;

  typedef std::list<net::CompletionCallback> CallbackList;
  CallbackList to_run_when_initialized_;

  // Set to true when the app is on the background. When the app is in the
  // background we can write the index much more frequently, to insure fresh
  // index on next startup.
  bool app_on_background_;
};

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_H_
