// Copyright (c) 2012 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 QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
#define QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_

#include <list>
#include <map>
#include <memory>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "quic/core/http/spdy_utils.h"
#include "quic/platform/api/quic_containers.h"
#include "quic/platform/api/quic_mutex.h"
#include "quic/tools/quic_backend_response.h"
#include "quic/tools/quic_simple_server_backend.h"
#include "quic/tools/quic_url.h"
#include "spdy/core/spdy_framer.h"

namespace quic {

// In-memory cache for HTTP responses.
// Reads from disk cache generated by:
// `wget -p --save_headers <url>`
class QuicMemoryCacheBackend : public QuicSimpleServerBackend {
 public:
  // Class to manage loading a resource file into memory.  There are
  // two uses: called by InitializeBackend to load resources
  // from files, and recursively called when said resources specify
  // server push associations.
  class ResourceFile {
   public:
    explicit ResourceFile(const std::string& file_name);
    ResourceFile(const ResourceFile&) = delete;
    ResourceFile& operator=(const ResourceFile&) = delete;
    virtual ~ResourceFile();

    void Read();

    // |base| is |file_name_| with |cache_directory| prefix stripped.
    void SetHostPathFromBase(absl::string_view base);

    const std::string& file_name() { return file_name_; }

    absl::string_view host() { return host_; }

    absl::string_view path() { return path_; }

    const spdy::Http2HeaderBlock& spdy_headers() { return spdy_headers_; }

    absl::string_view body() { return body_; }

    const std::vector<absl::string_view>& push_urls() { return push_urls_; }

   private:
    void HandleXOriginalUrl();
    absl::string_view RemoveScheme(absl::string_view url);

    std::string file_name_;
    std::string file_contents_;
    absl::string_view body_;
    spdy::Http2HeaderBlock spdy_headers_;
    absl::string_view x_original_url_;
    std::vector<absl::string_view> push_urls_;
    std::string host_;
    std::string path_;
  };

  QuicMemoryCacheBackend();
  QuicMemoryCacheBackend(const QuicMemoryCacheBackend&) = delete;
  QuicMemoryCacheBackend& operator=(const QuicMemoryCacheBackend&) = delete;
  ~QuicMemoryCacheBackend() override;

  // Retrieve a response from this cache for a given host and path..
  // If no appropriate response exists, nullptr is returned.
  const QuicBackendResponse* GetResponse(absl::string_view host,
                                         absl::string_view path) const;

  // Adds a simple response to the cache.  The response headers will
  // only contain the "content-length" header with the length of |body|.
  void AddSimpleResponse(absl::string_view host,
                         absl::string_view path,
                         int response_code,
                         absl::string_view body);

  // Add a simple response to the cache as AddSimpleResponse() does, and add
  // some server push resources(resource path, corresponding response status and
  // path) associated with it.
  // Push resource implicitly come from the same host.
  void AddSimpleResponseWithServerPushResources(
      absl::string_view host,
      absl::string_view path,
      int response_code,
      absl::string_view body,
      std::list<QuicBackendResponse::ServerPushInfo> push_resources);

  // Add a response to the cache.
  void AddResponse(absl::string_view host,
                   absl::string_view path,
                   spdy::Http2HeaderBlock response_headers,
                   absl::string_view response_body);

  // Add a response, with trailers, to the cache.
  void AddResponse(absl::string_view host,
                   absl::string_view path,
                   spdy::Http2HeaderBlock response_headers,
                   absl::string_view response_body,
                   spdy::Http2HeaderBlock response_trailers);

  // Add a response, with 103 Early Hints, to the cache.
  void AddResponseWithEarlyHints(
      absl::string_view host,
      absl::string_view path,
      spdy::Http2HeaderBlock response_headers,
      absl::string_view response_body,
      const std::vector<spdy::Http2HeaderBlock>& early_hints);

  // Simulate a special behavior at a particular path.
  void AddSpecialResponse(
      absl::string_view host,
      absl::string_view path,
      QuicBackendResponse::SpecialResponseType response_type);

  void AddSpecialResponse(
      absl::string_view host,
      absl::string_view path,
      spdy::Http2HeaderBlock response_headers,
      absl::string_view response_body,
      QuicBackendResponse::SpecialResponseType response_type);

  // Sets a default response in case of cache misses.  Takes ownership of
  // 'response'.
  void AddDefaultResponse(QuicBackendResponse* response);

  // Once called, URLs which have a numeric path will send a dynamically
  // generated response of that many bytes.
  void GenerateDynamicResponses();

  // Find all the server push resources associated with |request_url|.
  std::list<QuicBackendResponse::ServerPushInfo> GetServerPushResources(
      std::string request_url);

  // Implements the functions for interface QuicSimpleServerBackend
  // |cache_cirectory| can be generated using `wget -p --save-headers <url>`.
  bool InitializeBackend(const std::string& cache_directory) override;
  bool IsBackendInitialized() const override;
  void FetchResponseFromBackend(
      const spdy::Http2HeaderBlock& request_headers,
      const std::string& request_body,
      QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;
  void CloseBackendResponseStream(
      QuicSimpleServerBackend::RequestHandler* quic_server_stream) override;

 private:
  void AddResponseImpl(absl::string_view host,
                       absl::string_view path,
                       QuicBackendResponse::SpecialResponseType response_type,
                       spdy::Http2HeaderBlock response_headers,
                       absl::string_view response_body,
                       spdy::Http2HeaderBlock response_trailers,
                       const std::vector<spdy::Http2HeaderBlock>& early_hints);

  std::string GetKey(absl::string_view host, absl::string_view path) const;

  // Add some server push urls with given responses for specified
  // request if these push resources are not associated with this request yet.
  void MaybeAddServerPushResources(
      absl::string_view request_host,
      absl::string_view request_path,
      std::list<QuicBackendResponse::ServerPushInfo> push_resources);

  // Check if push resource(push_host/push_path) associated with given request
  // url already exists in server push map.
  bool PushResourceExistsInCache(std::string original_request_url,
                                 QuicBackendResponse::ServerPushInfo resource);

  // Cached responses.
  absl::flat_hash_map<std::string, std::unique_ptr<QuicBackendResponse>>
      responses_ QUIC_GUARDED_BY(response_mutex_);

  // The default response for cache misses, if set.
  std::unique_ptr<QuicBackendResponse> default_response_
      QUIC_GUARDED_BY(response_mutex_);

  // The generate bytes response, if set.
  std::unique_ptr<QuicBackendResponse> generate_bytes_response_
      QUIC_GUARDED_BY(response_mutex_);

  // A map from request URL to associated server push responses (if any).
  std::multimap<std::string, QuicBackendResponse::ServerPushInfo>
      server_push_resources_ QUIC_GUARDED_BY(response_mutex_);

  // Protects against concurrent access from test threads setting responses, and
  // server threads accessing those responses.
  mutable QuicMutex response_mutex_;
  bool cache_initialized_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_TOOLS_QUIC_MEMORY_CACHE_BACKEND_H_
