// Copyright (c) 2011 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_APPCACHE_APPCACHE_HOST_H_
#define CONTENT_BROWSER_APPCACHE_APPCACHE_HOST_H_

#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_service_impl.h"
#include "content/browser/appcache/appcache_storage.h"
#include "content/common/appcache_interfaces.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
#include "url/gurl.h"

namespace net {
class URLRequest;
}  // namespace net

namespace content {
FORWARD_DECLARE_TEST(AppCacheGroupTest, CleanupUnusedGroup);
FORWARD_DECLARE_TEST(AppCacheGroupTest, QueueUpdate);
FORWARD_DECLARE_TEST(AppCacheHostTest, Basic);
FORWARD_DECLARE_TEST(AppCacheHostTest, SelectNoCache);
FORWARD_DECLARE_TEST(AppCacheHostTest, ForeignEntry);
FORWARD_DECLARE_TEST(AppCacheHostTest, FailedCacheLoad);
FORWARD_DECLARE_TEST(AppCacheHostTest, FailedGroupLoad);
FORWARD_DECLARE_TEST(AppCacheHostTest, SetSwappableCache);
FORWARD_DECLARE_TEST(AppCacheHostTest, ForDedicatedWorker);
FORWARD_DECLARE_TEST(AppCacheHostTest, SelectCacheAllowed);
FORWARD_DECLARE_TEST(AppCacheHostTest, SelectCacheBlocked);
FORWARD_DECLARE_TEST(AppCacheTest, CleanupUnusedCache);
class AppCache;
class AppCacheFrontend;
class AppCacheGroupTest;
class AppCacheHostTest;
class AppCacheRequestHandler;
class AppCacheRequestHandlerTest;
class AppCacheStorageImplTest;
class AppCacheTest;
class AppCacheUpdateJobTest;

typedef base::Callback<void(AppCacheStatus, void*)> GetStatusCallback;
typedef base::Callback<void(bool, void*)> StartUpdateCallback;
typedef base::Callback<void(bool, void*)> SwapCacheCallback;

// Server-side representation of an application cache host.
class CONTENT_EXPORT AppCacheHost
    : public AppCacheStorage::Delegate,
      public AppCacheGroup::UpdateObserver,
      public AppCacheServiceImpl::Observer {
 public:

  class CONTENT_EXPORT Observer {
   public:
    // Called just after the cache selection algorithm completes.
    virtual void OnCacheSelectionComplete(AppCacheHost* host) = 0;

    // Called just prior to the instance being deleted.
    virtual void OnDestructionImminent(AppCacheHost* host) = 0;

    virtual ~Observer() {}
  };

  AppCacheHost(int host_id, AppCacheFrontend* frontend,
               AppCacheServiceImpl* service);
  virtual ~AppCacheHost();

  // Adds/removes an observer, the AppCacheHost does not take
  // ownership of the observer.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Support for cache selection and scriptable method calls.
  void SelectCache(const GURL& document_url,
                   const int64 cache_document_was_loaded_from,
                   const GURL& manifest_url);
  void SelectCacheForWorker(int parent_process_id,
                            int parent_host_id);
  void SelectCacheForSharedWorker(int64 appcache_id);
  void MarkAsForeignEntry(const GURL& document_url,
                          int64 cache_document_was_loaded_from);
  void GetStatusWithCallback(const GetStatusCallback& callback,
                             void* callback_param);
  void StartUpdateWithCallback(const StartUpdateCallback& callback,
                               void* callback_param);
  void SwapCacheWithCallback(const SwapCacheCallback& callback,
                             void* callback_param);

  // Called prior to the main resource load. When the system contains multiple
  // candidates for a main resource load, the appcache preferred by the host
  // that created this host is used to break ties.
  void SetSpawningHostId(int spawning_process_id, int spawning_host_id);

  // May return NULL if the spawning host context has been closed, or if a
  // spawning host context was never identified.
  const AppCacheHost* GetSpawningHost() const;

  const GURL& preferred_manifest_url() const {
    return preferred_manifest_url_;
  }
  void set_preferred_manifest_url(const GURL& url) {
    preferred_manifest_url_ = url;
  }

  // Support for loading resources out of the appcache.
  // May return NULL if the request isn't subject to retrieval from an appache.
  AppCacheRequestHandler* CreateRequestHandler(
      net::URLRequest* request,
      ResourceType resource_type);

  // Support for devtools inspecting appcache resources.
  void GetResourceList(std::vector<AppCacheResourceInfo>* resource_infos);

  // Breaks any existing association between this host and a cache.
  // 'manifest_url' is sent to DevTools as the manifest url that could have
  // been associated before or could be associated later with this host.
  // Associations are broken either thru the cache selection algorithm
  // implemented in this class, or by the update algorithm (see
  // AppCacheUpdateJob).
  void AssociateNoCache(const GURL& manifest_url);

  // Establishes an association between this host and an incomplete cache.
  // 'manifest_url' is manifest url of the cache group being updated.
  // Associations with incomplete caches are established by the update algorithm
  // (see AppCacheUpdateJob).
  void AssociateIncompleteCache(AppCache* cache, const GURL& manifest_url);

  // Establishes an association between this host and a complete cache.
  // Associations with complete caches are established either thru the cache
  // selection algorithm implemented (in this class), or by the update algorithm
  // (see AppCacheUpdateJob).
  void AssociateCompleteCache(AppCache* cache);

  // Adds a reference to the newest complete cache in a group, unless it's the
  // same as the cache that is currently associated with the host.
  void SetSwappableCache(AppCacheGroup* group);

  // Used to ensure that a loaded appcache survives a frame navigation.
  void LoadMainResourceCache(int64 cache_id);

  // Used to notify the host that a namespace resource is being delivered as
  // the main resource of the page and to provide its url.
  void NotifyMainResourceIsNamespaceEntry(const GURL& namespace_entry_url);

  // Used to notify the host that the main resource was blocked by a policy. To
  // work properly, this method needs to by invoked prior to cache selection.
  void NotifyMainResourceBlocked(const GURL& manifest_url);

  // Used by the update job to keep track of which hosts are associated
  // with which pending master entries.
  const GURL& pending_master_entry_url() const {
    return new_master_entry_url_;
  }

  int host_id() const { return host_id_; }
  AppCacheServiceImpl* service() const { return service_; }
  AppCacheStorage* storage() const { return storage_; }
  AppCacheFrontend* frontend() const { return frontend_; }
  AppCache* associated_cache() const { return associated_cache_.get(); }

  bool is_selection_pending() const {
    return pending_selected_cache_id_ != kAppCacheNoCacheId ||
           !pending_selected_manifest_url_.is_empty();
  }

  const GURL& first_party_url() const { return first_party_url_; }

  // Methods to support cross site navigations.
  void PrepareForTransfer();
  void CompleteTransfer(int host_id, AppCacheFrontend* frontend);

 private:
  friend class content::AppCacheHostTest;
  friend class content::AppCacheStorageImplTest;
  friend class content::AppCacheRequestHandlerTest;
  friend class content::AppCacheUpdateJobTest;

  AppCacheStatus GetStatus();
  void LoadSelectedCache(int64 cache_id);
  void LoadOrCreateGroup(const GURL& manifest_url);

  // See public Associate*Host() methods above.
  void AssociateCacheHelper(AppCache* cache, const GURL& manifest_url);

  // AppCacheStorage::Delegate impl
  virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE;
  virtual void OnGroupLoaded(AppCacheGroup* group,
                             const GURL& manifest_url) OVERRIDE;
  // AppCacheServiceImpl::Observer impl
  virtual void OnServiceReinitialized(
      AppCacheStorageReference* old_storage_ref) OVERRIDE;

  void FinishCacheSelection(AppCache* cache, AppCacheGroup* group);
  void DoPendingGetStatus();
  void DoPendingStartUpdate();
  void DoPendingSwapCache();

  void ObserveGroupBeingUpdated(AppCacheGroup* group);

  // AppCacheGroup::UpdateObserver methods.
  virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE;

  // Returns true if this host is for a dedicated worker context.
  bool is_for_dedicated_worker() const {
    return parent_host_id_ != kAppCacheNoHostId;
  }

  // Returns the parent context's host instance. This is only valid
  // to call when this instance is_for_dedicated_worker.
  AppCacheHost* GetParentAppCacheHost() const;

  // Identifies the corresponding appcache host in the child process.
  int host_id_;

  // Information about the host that created this one; the manifest
  // preferred by our creator influences which cache our main resource
  // should be loaded from.
  int spawning_host_id_;
  int spawning_process_id_;
  GURL preferred_manifest_url_;

  // Hosts for dedicated workers are special cased to shunt
  // request handling off to the dedicated worker's parent.
  // The scriptable api is not accessible in dedicated workers
  // so the other aspects of this class are not relevant for
  // these special case instances.
  int parent_host_id_;
  int parent_process_id_;

  // Defined prior to refs to AppCaches and Groups because destruction
  // order matters, the disabled_storage_reference_ must outlive those
  // objects. See additional comments for the storage_ member.
  scoped_refptr<AppCacheStorageReference> disabled_storage_reference_;

  // The cache associated with this host, if any.
  scoped_refptr<AppCache> associated_cache_;

  // Hold a reference to the newest complete cache (if associated cache is
  // not the newest) to keep the newest cache in existence while the app cache
  // group is in use. The newest complete cache may have no associated hosts
  // holding any references to it and would otherwise be deleted prematurely.
  scoped_refptr<AppCache> swappable_cache_;

  // Keep a reference to the group being updated until the update completes.
  scoped_refptr<AppCacheGroup> group_being_updated_;

  // Similarly, keep a reference to the newest cache of the group until the
  // update completes. When adding a new master entry to a cache that is not
  // in use in any other host, this reference keeps the cache in  memory.
  scoped_refptr<AppCache> newest_cache_of_group_being_updated_;

  // Keep a reference to the cache of the main resource so it survives frame
  // navigations.
  scoped_refptr<AppCache> main_resource_cache_;
  int64 pending_main_resource_cache_id_;

  // Cache loading is async, if we're loading a specific cache or group
  // for the purposes of cache selection, one or the other of these will
  // indicate which cache or group is being loaded.
  int64 pending_selected_cache_id_;
  GURL pending_selected_manifest_url_;

  // A new master entry to be added to the cache, may be empty.
  GURL new_master_entry_url_;

  // The frontend proxy to deliver notifications to the child process.
  AppCacheFrontend* frontend_;

  // Our central service object.
  AppCacheServiceImpl* service_;

  // And the equally central storage object, with a twist. In some error
  // conditions the storage object gets recreated and reinitialized. The
  // disabled_storage_reference_ (defined earlier) allows for cleanup of an
  // instance that got disabled  after we had latched onto it. In normal
  // circumstances, disabled_storage_reference_ is expected to be NULL.
  // When non-NULL both storage_ and disabled_storage_reference_ refer to the
  // same instance.
  AppCacheStorage* storage_;

  // Since these are synchronous scriptable API calls in the client, there can
  // only be one type of callback pending. Also, we have to wait until we have a
  // cache selection prior to responding to these calls, as cache selection
  // involves async loading of a cache or a group from storage.
  GetStatusCallback pending_get_status_callback_;
  StartUpdateCallback pending_start_update_callback_;
  SwapCacheCallback pending_swap_cache_callback_;
  void* pending_callback_param_;

  // True if an intercept or fallback namespace resource was
  // delivered as the main resource.
  bool main_resource_was_namespace_entry_;
  GURL namespace_entry_url_;

  // True if requests for this host were blocked by a policy.
  bool main_resource_blocked_;
  GURL blocked_manifest_url_;

  // Tells if info about associated cache is pending. Info is pending
  // when update job has not returned success yet.
  bool associated_cache_info_pending_;

  // List of objects observing us.
  ObserverList<Observer> observers_;

  // Used to inform the QuotaManager of what origins are currently in use.
  GURL origin_in_use_;

  // First party url to be used in policy checks.
  GURL first_party_url_;

  FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, CleanupUnusedGroup);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, QueueUpdate);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, Basic);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectNoCache);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, ForeignEntry);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, FailedCacheLoad);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, FailedGroupLoad);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SetSwappableCache);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, ForDedicatedWorker);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheAllowed);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheBlocked);
  FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, CleanupUnusedCache);

  DISALLOW_COPY_AND_ASSIGN(AppCacheHost);
};

}  // namespace content

#endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_HOST_H_
