// 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.
  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 WriteData(const GURL& resource_url,
                 const GURL& origin_lock,
                 const base::Time& response_time,
                 base::span<const uint8_t> 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, kWrite, kDelete, kGetBackend };

  // Data streams corresponding to each entry.
  enum { kDataIndex = 1 };

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

  // The requests that are received while tha backend is being initialized
  // are recorded in pending operations list. This function issues all pending
  // operations.
  void IssuePendingOperations();

  // Write entry to cache
  void WriteDataImpl(const std::string& key,
                     scoped_refptr<net::IOBufferWithSize> buffer);
  void CompleteForWriteData(scoped_refptr<net::IOBufferWithSize> buffer,
                            const std::string& key,
                            disk_cache::EntryResult result);
  void WriteDataCompleted(const std::string& key, int rv);

  // Fetch entry from cache
  void FetchEntryImpl(const std::string& key, ReadDataCallback);
  void OpenCompleteForReadData(ReadDataCallback callback,
                               const std::string& key,
                               disk_cache::EntryResult result);
  void ReadResponseTimeComplete(const std::string& key,
                                ReadDataCallback callback,
                                scoped_refptr<net::IOBufferWithSize> buffer,
                                disk_cache::Entry* entry,
                                int rv);
  void ReadCodeComplete(const std::string& key,
                        ReadDataCallback callback,
                        scoped_refptr<net::IOBufferWithSize> buffer,
                        int64_t raw_response_time,
                        int rv);

  // Delete entry from cache
  void DeleteEntryImpl(const std::string& key);

  // Issues the queued operation at the front of the queue for the given |key|.
  void IssueQueuedOperationForEntry(const std::string& key);
  // Enqueues into the list if there is an in-progress operation. Otherwise
  // creates an entry to indicate there is an active operation.
  bool EnqueueAsPendingOperation(const std::string& key,
                                 std::unique_ptr<PendingOperation> op);
  void IssueOperation(PendingOperation* op);

  void DoPendingGetBackend(GetBackendCallback callback);

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

  std::vector<std::unique_ptr<PendingOperation>> pending_ops_;

  // Map from key to queue ops.
  std::map<std::string, base::queue<std::unique_ptr<PendingOperation>>>
      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_
