// Copyright 2017 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_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_H_

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

#include "base/callback_forward.h"
#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_scheduler.h"
#include "content/browser/background_fetch/storage/database_task.h"
#include "content/browser/background_fetch/storage/get_initialization_data_task.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h"
#include "url/origin.h"

namespace storage {
class BlobDataHandle;
class QuotaManagerProxy;
}

namespace content {

class BackgroundFetchDataManagerObserver;
class BackgroundFetchRequestInfo;
class BackgroundFetchRequestMatchParams;
class BrowserContext;
class CacheStorageManager;
class ChromeBlobStorageContext;
class ServiceWorkerContextWrapper;

// The BackgroundFetchDataManager is a wrapper around persistent storage (the
// Service Worker database), exposing APIs for the read and write queries needed
// for Background Fetch.
//
// There must only be a single instance of this class per StoragePartition, and
// it must only be used on the IO thread, since it relies on there being no
// other code concurrently reading/writing the Background Fetch keys of the same
// Service Worker database (except for deletions, e.g. it's safe for the Service
// Worker code to remove a ServiceWorkerRegistration and all its keys).
//
// Storage schema is documented in storage/README.md
class CONTENT_EXPORT BackgroundFetchDataManager
    : public background_fetch::DatabaseTaskHost {
 public:
  using GetInitializationDataCallback = base::OnceCallback<void(
      blink::mojom::BackgroundFetchError,
      std::vector<background_fetch::BackgroundFetchInitializationData>)>;
  using SettledFetchesCallback = base::OnceCallback<void(
      blink::mojom::BackgroundFetchError,
      std::vector<blink::mojom::BackgroundFetchSettledFetchPtr>)>;
  using GetRegistrationCallback =
      base::OnceCallback<void(blink::mojom::BackgroundFetchError,
                              blink::mojom::BackgroundFetchRegistrationPtr)>;
  using MarkRegistrationForDeletionCallback =
      base::OnceCallback<void(blink::mojom::BackgroundFetchError,
                              blink::mojom::BackgroundFetchFailureReason)>;
  using GetRequestBlobCallback =
      base::OnceCallback<void(blink::mojom::BackgroundFetchError,
                              blink::mojom::SerializedBlobPtr)>;
  using MarkRequestCompleteCallback =
      base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
  using NextRequestCallback =
      base::OnceCallback<void(blink::mojom::BackgroundFetchError,
                              scoped_refptr<BackgroundFetchRequestInfo>)>;

  BackgroundFetchDataManager(
      BrowserContext* browser_context,
      scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
      scoped_refptr<CacheStorageContextImpl> cache_storage_context,
      scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy);

  ~BackgroundFetchDataManager() override;

  // Grabs a reference to CacheStorageManager.
  virtual void InitializeOnIOThread();

  // Adds or removes the given |observer| to this data manager instance.
  void AddObserver(BackgroundFetchDataManagerObserver* observer);
  void RemoveObserver(BackgroundFetchDataManagerObserver* observer);

  // Gets the required data to initialize BackgroundFetchContext with the
  // appropriate JobControllers. This will be called when BackgroundFetchContext
  // is being intialized on the IO thread.
  void GetInitializationData(GetInitializationDataCallback callback);

  // Creates and stores a new registration with the given properties. Will
  // invoke the |callback| when the registration has been created, which may
  // fail due to invalid input or storage errors.
  void CreateRegistration(
      const BackgroundFetchRegistrationId& registration_id,
      std::vector<blink::mojom::FetchAPIRequestPtr> requests,
      blink::mojom::BackgroundFetchOptionsPtr options,
      const SkBitmap& icon,
      bool start_paused,
      GetRegistrationCallback callback);

  // Get the BackgroundFetchRegistration.
  void GetRegistration(int64_t service_worker_registration_id,
                       const url::Origin& origin,
                       const std::string& developer_id,
                       GetRegistrationCallback callback);

  // Reads the settled fetches for the given |registration_id| based on
  // |match_params|. Both the Request and Response objects will be initialised
  // based on the stored data. Will invoke the |callback| when the list of
  // fetches has been compiled.
  void MatchRequests(
      const BackgroundFetchRegistrationId& registration_id,
      std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
      SettledFetchesCallback callback);

  // Retrieves the next pending request for |registration_id| and invoke
  // |callback| with it.
  void PopNextRequest(const BackgroundFetchRegistrationId& registration_id,
                      NextRequestCallback callback);

  // Retrieves the request blob associated with |request_info|. THis should be
  // called for requests that are known to have a blob.
  void GetRequestBlob(
      const BackgroundFetchRegistrationId& registration_id,
      const scoped_refptr<BackgroundFetchRequestInfo>& request_info,
      GetRequestBlobCallback callback);

  // Marks |request_info| as complete and calls |callback| when done.
  void MarkRequestAsComplete(
      const BackgroundFetchRegistrationId& registration_id,
      scoped_refptr<BackgroundFetchRequestInfo> request_info,
      MarkRequestCompleteCallback callback);

  // Marks that the
  // backgroundfetchsuccess/backgroundfetchfail/backgroundfetchabort event is
  // being dispatched. It's not possible to call DeleteRegistration at this
  // point as JavaScript may hold a reference to a BackgroundFetchRegistration
  // object and we need to keep the corresponding data around until the last
  // such reference is released (or until shutdown). We can't just move the
  // Background Fetch registration's data to RAM as it might consume too much
  // memory. So instead this step disassociates the |developer_id| from the
  // |unique_id|, so that existing JS objects with a reference to |unique_id|
  // can still access the data, but it can no longer be reached using GetIds or
  // GetRegistration. If |check_for_failure| is true, the task will also check
  // whether there is any associated failure reason with the fetches. This
  // helps figure out whether a success or fail event should be dispatched.
  void MarkRegistrationForDeletion(
      const BackgroundFetchRegistrationId& registration_id,
      bool check_for_failure,
      MarkRegistrationForDeletionCallback callback);

  // Deletes the registration identified by |registration_id|. Should only be
  // called once the refcount of JavaScript BackgroundFetchRegistration objects
  // referring to this registration drops to zero. Will invoke the |callback|
  // when the registration has been deleted from storage.
  void DeleteRegistration(const BackgroundFetchRegistrationId& registration_id,
                          HandleBackgroundFetchErrorCallback callback);

  // List all Background Fetch registration |developer_id|s for a Service
  // Worker.
  void GetDeveloperIdsForServiceWorker(
      int64_t service_worker_registration_id,
      const url::Origin& origin,
      blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);

  const base::ObserverList<BackgroundFetchDataManagerObserver>::Unchecked&
  observers() {
    return observers_;
  }

  void ShutdownOnIO();

 private:
  FRIEND_TEST_ALL_PREFIXES(BackgroundFetchDataManagerTest, Cleanup);
  friend class BackgroundFetchDataManagerTest;
  friend class BackgroundFetchTestDataManager;
  friend class background_fetch::DatabaseTask;

  // Accessors for tests and DatabaseTasks.
  ServiceWorkerContextWrapper* service_worker_context() const {
    return service_worker_context_.get();
  }
  scoped_refptr<CacheStorageManager> cache_manager() const {
    return cache_manager_;
  }
  std::set<std::string>& ref_counted_unique_ids() {
    return ref_counted_unique_ids_;
  }
  ChromeBlobStorageContext* blob_storage_context() const {
    return blob_storage_context_.get();
  }
  storage::QuotaManagerProxy* quota_manager_proxy() const {
    return quota_manager_proxy_.get();
  }

  void AddDatabaseTask(std::unique_ptr<background_fetch::DatabaseTask> task);

  // DatabaseTaskHost implementation.
  void OnTaskFinished(background_fetch::DatabaseTask* task) override;
  BackgroundFetchDataManager* data_manager() override;
  base::WeakPtr<background_fetch::DatabaseTaskHost> GetWeakPtr() override;

  void Cleanup();

  // Get a CacheStorageHandle for the given |origin| and |unique_id|.  This will
  // either come from an existing CacheStorageHandle or will cause the
  // CacheStorage to be opened.
  CacheStorageHandle GetOrOpenCacheStorage(const url::Origin& origin,
                                           const std::string& unique_id);

  // Release the CacheStorageHandle for the given |unique_id|, if
  // it's open.  DoomCache should be called prior to releasing the handle.
  // There must be an entry in |cache_storage_handle_map_| for the given
  // |unique_id|.
  void ReleaseCacheStorage(const std::string& unique_id);

  // Whether Shutdown was called on BackgroundFetchContext.
  bool shutting_down_ = false;

  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;

  scoped_refptr<CacheStorageContextImpl> cache_storage_context_;

  scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;

  // BackgroundFetch stores its own reference to CacheStorageManager
  // in case StoragePartitionImpl is destroyed, which releases the reference.
  scoped_refptr<CacheStorageManager> cache_manager_;

  // The blob storage request with which response information will be stored.
  scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;

  // Pending database operations, serialized to ensure consistency.
  // Invariant: the frontmost task, if any, has already been started.
  base::queue<std::unique_ptr<background_fetch::DatabaseTask>> database_tasks_;

  base::ObserverList<BackgroundFetchDataManagerObserver>::Unchecked observers_;

  // The |unique_id|s of registrations that have been deactivated since the
  // browser was last started. They will be automatically deleted when the
  // refcount of JavaScript objects that refers to them goes to zero, unless
  // the browser is shutdown first.
  std::set<std::string> ref_counted_unique_ids_;

  // A map of open CacheStorageHandle objects keyed by the registration
  // |unique_id|. These handles are created opportunistically in
  // GetOrOpenCacheStorage(). They are cleared after the Cache has been
  // deleted and ReleaseCacheStorage() is called.
  // TODO(crbug.com/711354): Possibly update key when CORS support is added.
  std::map<std::string, CacheStorageHandle> cache_storage_handle_map_;

  base::WeakPtrFactory<BackgroundFetchDataManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(BackgroundFetchDataManager);
};

}  // namespace content

#endif  // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_H_
