// Copyright 2018 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_CODE_CACHE_GENERATED_CODE_CACHE_H_
#define CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_

#include <queue>

#include "base/containers/queue.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "net/base/io_buffer.h"
#include "net/disk_cache/disk_cache.h"
#include "url/origin.h"

namespace content {

// Cache for storing generated code from the renderer on the disk. This cache
// uses |resource_url| + |origin_lock| as a key for storing the generated code.
// |resource_url| is the url corresponding to the requested resource.
// |origin_lock| is the origin that the renderer which requested this resource
// is locked to. This is used to enforce site isolation policy on cached code.
// For example, if SitePerProcess is enabled and http://script.com/script1.js is
// requested by http://example.com, then http://script.com/script.js is the
// resource_url and http://example.com is the origin_lock.
//
// The key is generated by concatenating the serialized url and origin lock
// with a separator in between. The separator is non-valid URL characters, to
// prevent any attacks by crafting the URLs. |origin_lock| could be empty when
// renderer is not locked to an origin (ex:SitePerProcess is disabled) and it
// is safe to use only |resource_url| as the key in such cases.
//
// This uses a simple disk_cache backend. It just stores one data stream and
// stores response_time + generated code as one data blob.
//
// There exists one cache per storage partition and is owned by the storage
// partition. This cache is created, accessed and destroyed on the I/O
// thread.
class CONTENT_EXPORT GeneratedCodeCache {
 public:
  using ReadDataCallback =
      base::RepeatingCallback<void(const base::Time&,
                                   mojo_base::BigBuffer data)>;
  using GetBackendCallback = base::OnceCallback<void(disk_cache::Backend*)>;

  // Cache type. Used for collecting statistics for JS and Wasm in separate
  // buckets.
  enum CodeCacheType { kJavaScript, kWebAssembly };

  // Used for collecting statistics about cache behaviour.
  enum CacheEntryStatus {
    kHit,
    kMiss,
    kClear,
    kUpdate,
    kCreate,
    kError,
    kIncompleteEntry,
    kWriteFailed,
    kMaxValue = kWriteFailed
  };

  // Returns the resource URL from the key. The key has the format prefix +
  // resource URL + separator + requesting origin. This function extracts and
  // returns resource URL from the key, or the empty string if key is invalid.
  static std::string GetResourceURLFromKey(const std::string& key);

  // Creates a GeneratedCodeCache with the specified path and the maximum size.
  // If |max_size_bytes| is 0, then disk_cache picks a default size based on
  // some heuristics.
  GeneratedCodeCache(const base::FilePath& path,
                     int max_size_bytes,
                     CodeCacheType cache_type);

  ~GeneratedCodeCache();

  // Runs the callback with a raw pointer to the backend. If we could not create
  // the backend then it will return a null. This runs the callback
  // synchronously if the backend is already open or asynchronously on the
  // completion of a pending backend creation.
  void GetBackend(GetBackendCallback callback);

  // Writes data to the cache. If there is an entry corresponding to
  // <|resource_url|, |origin_lock|> this overwrites the existing data. If
  // there is no entry it creates a new one.
  void WriteEntry(const GURL& resource_url,
                  const GURL& origin_lock,
                  const base::Time& response_time,
                  mojo_base::BigBuffer data);

  // Fetch entry corresponding to <resource_url, origin_lock> from the cache
  // and return it using the ReadDataCallback.
  void FetchEntry(const GURL& resource_url,
                  const GURL& origin_lock,
                  ReadDataCallback);

  // Delete the entry corresponding to <resource_url, origin_lock>
  void DeleteEntry(const GURL& resource_url, const GURL& origin_lock);

  // Should be only used for tests. Sets the last accessed timestamp of an
  // entry.
  void SetLastUsedTimeForTest(const GURL& resource_url,
                              const GURL& origin_lock,
                              base::Time time,
                              base::RepeatingCallback<void(void)> callback);

  const base::FilePath& path() const { return path_; }

 private:
  class PendingOperation;
  using ScopedBackendPtr = std::unique_ptr<disk_cache::Backend>;

  // State of the backend.
  enum BackendState { kInitializing, kInitialized, kFailed };

  // The operation requested.
  enum Operation {
    kFetch,
    kFetchWithSHAKey,
    kWrite,
    kWriteWithSHAKey,
    kDelete,
    kGetBackend
  };

  // Data streams corresponding to each entry.
  enum { kSmallDataStream = 0, kLargeDataStream = 1 };

  // Creates a simple_disk_cache backend.
  void CreateBackend();
  void DidCreateBackend(
      scoped_refptr<base::RefCountedData<ScopedBackendPtr>> backend_ptr,
      int rv);

  // Adds operation to the appropriate queue.
  void EnqueueOperation(std::unique_ptr<PendingOperation> op);

  // Issues ops that were received while the backend was being initialized.
  void IssuePendingOperations();
  void IssueOperation(PendingOperation* op);

  // Writes entry to cache.
  void WriteEntryImpl(PendingOperation* op);
  void OpenCompleteForWrite(PendingOperation* op,
                            disk_cache::EntryResult result);
  void WriteSmallBufferComplete(PendingOperation* op, int rv);
  void WriteLargeBufferComplete(PendingOperation* op, int rv);
  void WriteComplete(PendingOperation* op);

  // Fetches entry from cache.
  void FetchEntryImpl(PendingOperation* op);
  void OpenCompleteForRead(PendingOperation* op,
                           disk_cache::EntryResult result);
  void ReadSmallBufferComplete(PendingOperation* op, int rv);
  void ReadLargeBufferComplete(PendingOperation* op, int rv);
  void ReadComplete(PendingOperation* op);

  // Deletes entry from cache.
  void DeleteEntryImpl(PendingOperation* op);

  void DoomEntry(PendingOperation* op);

  // Issues the next operation on the queue for |key|.
  void IssueNextOperation(const std::string& key);
  // Removes |op| and issues the next operation on its queue.
  void CloseOperationAndIssueNext(PendingOperation* op);

  // Enqueues the operation issues it if there are no pending operations for
  // its key.
  void EnqueueOperationAndIssueIfNext(std::unique_ptr<PendingOperation> op);
  // Dequeues the operation and transfers ownership to caller.
  std::unique_ptr<PendingOperation> DequeueOperation(PendingOperation* op);

  void DoPendingGetBackend(PendingOperation* op);

  void OpenCompleteForSetLastUsedForTest(
      base::Time time,
      base::RepeatingCallback<void(void)> callback,
      disk_cache::EntryResult result);

  void CollectStatistics(GeneratedCodeCache::CacheEntryStatus status);

  std::unique_ptr<disk_cache::Backend> backend_;
  BackendState backend_state_;

  // Queue for operations received while initializing the backend.
  using PendingOperationQueue = base::queue<std::unique_ptr<PendingOperation>>;
  PendingOperationQueue pending_ops_;

  // Map from key to queue of pending operations.
  std::map<std::string, PendingOperationQueue> active_entries_map_;

  base::FilePath path_;
  int max_size_bytes_;
  CodeCacheType cache_type_;

  base::WeakPtrFactory<GeneratedCodeCache> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(GeneratedCodeCache);
};

}  // namespace content

#endif  // CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_
