// 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 <map>
#include <queue>

#include "base/containers/queue.h"
#include "base/files/file_path.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/base/network_isolation_key.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::OnceCallback<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 {
    // JavaScript from http(s) pages.
    kJavaScript,

    // WebAssembly from http(s) pages. This cache allows more total size and
    // more size per item than the JavaScript cache, since some
    // WebAssembly programs are very large.
    kWebAssembly,

    // JavaScript from chrome and chrome-untrusted pages. The resource URLs are
    // limited to only those fetched via chrome and chrome-untrusted schemes.
    // The cache size is limited to disk_cache::kMaxWebUICodeCacheSize.
    // Deduplication of very large items is disabled in this cache.
    kWebUIJavaScript,
  };

  // 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(const GeneratedCodeCache&) = delete;
  GeneratedCodeCache& operator=(const GeneratedCodeCache&) = delete;

  ~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 net::NetworkIsolationKey& nik,
                  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,
                  const net::NetworkIsolationKey& nik,
                  ReadDataCallback);

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

  // Should be only used for tests. Sets the last accessed timestamp of an
  // entry.
  void SetLastUsedTimeForTest(const GURL& resource_url,
                              const GURL& origin_lock,
                              const net::NetworkIsolationKey& nik,
                              base::Time time,
                              base::OnceClosure 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::OnceClosure callback,
                                         disk_cache::EntryResult result);

  void CollectStatistics(GeneratedCodeCache::CacheEntryStatus status);

  // Whether very large cache entries are deduplicated in this cache.
  // Deduplication is disabled in the WebUI code cache, as an additional defense
  // against privilege escalation in case there is a bug in the deduplication
  // logic.
  bool IsDeduplicationEnabled() const;

  bool ShouldDeduplicateEntry(uint32_t data_size) const;

  // Checks that the header data in the small buffer is valid. We may read cache
  // entries that were written by a previous version of Chrome which uses
  // obsolete formats. These reads should fail and be doomed as soon as
  // possible.
  bool IsValidHeader(scoped_refptr<net::IOBufferWithSize> small_buffer) const;

  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};
};

}  // namespace content

#endif  // CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_
