// Copyright 2013 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.

#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"

#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
#include "net/third_party/quiche/src/quic/tools/quic_backend_response.h"

namespace quic {
namespace test {

namespace {
typedef QuicBackendResponse Response;
typedef QuicBackendResponse::ServerPushInfo ServerPushInfo;
}  // namespace

class QuicMemoryCacheBackendTest : public QuicTest {
 protected:
  void CreateRequest(std::string host,
                     std::string path,
                     spdy::SpdyHeaderBlock* headers) {
    (*headers)[":method"] = "GET";
    (*headers)[":path"] = path;
    (*headers)[":authority"] = host;
    (*headers)[":scheme"] = "https";
  }

  std::string CacheDirectory() { return QuicGetTestMemoryCachePath(); }

  QuicMemoryCacheBackend cache_;
};

TEST_F(QuicMemoryCacheBackendTest, GetResponseNoMatch) {
  const Response* response =
      cache_.GetResponse("mail.google.com", "/index.html");
  ASSERT_FALSE(response);
}

TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseGetResponse) {
  std::string response_body("hello response");
  cache_.AddSimpleResponse("www.google.com", "/", 200, response_body);

  spdy::SpdyHeaderBlock request_headers;
  CreateRequest("www.google.com", "/", &request_headers);
  const Response* response = cache_.GetResponse("www.google.com", "/");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("200", response->headers().find(":status")->second);
  EXPECT_EQ(response_body.size(), response->body().length());
}

TEST_F(QuicMemoryCacheBackendTest, AddResponse) {
  const std::string kRequestHost = "www.foo.com";
  const std::string kRequestPath = "/";
  const std::string kResponseBody("hello response");

  spdy::SpdyHeaderBlock response_headers;
  response_headers[":status"] = "200";
  response_headers["content-length"] =
      QuicTextUtils::Uint64ToString(kResponseBody.size());

  spdy::SpdyHeaderBlock response_trailers;
  response_trailers["key-1"] = "value-1";
  response_trailers["key-2"] = "value-2";
  response_trailers["key-3"] = "value-3";

  cache_.AddResponse(kRequestHost, "/", response_headers.Clone(), kResponseBody,
                     response_trailers.Clone());

  const Response* response = cache_.GetResponse(kRequestHost, kRequestPath);
  EXPECT_EQ(response->headers(), response_headers);
  EXPECT_EQ(response->body(), kResponseBody);
  EXPECT_EQ(response->trailers(), response_trailers);
}

TEST_F(QuicMemoryCacheBackendTest, ReadsCacheDir) {
  cache_.InitializeBackend(CacheDirectory());
  const Response* response =
      cache_.GetResponse("test.example.com", "/index.html");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("200", response->headers().find(":status")->second);
  // Connection headers are not valid in HTTP/2.
  EXPECT_FALSE(QuicContainsKey(response->headers(), "connection"));
  EXPECT_LT(0U, response->body().length());
}

TEST_F(QuicMemoryCacheBackendTest, ReadsCacheDirWithServerPushResource) {
  cache_.InitializeBackend(CacheDirectory() + "_with_push");
  std::list<ServerPushInfo> resources =
      cache_.GetServerPushResources("test.example.com/");
  ASSERT_EQ(1UL, resources.size());
}

TEST_F(QuicMemoryCacheBackendTest, ReadsCacheDirWithServerPushResources) {
  cache_.InitializeBackend(CacheDirectory() + "_with_push");
  std::list<ServerPushInfo> resources =
      cache_.GetServerPushResources("test.example.com/index2.html");
  ASSERT_EQ(2UL, resources.size());
}

TEST_F(QuicMemoryCacheBackendTest, UsesOriginalUrl) {
  cache_.InitializeBackend(CacheDirectory());
  const Response* response =
      cache_.GetResponse("test.example.com", "/site_map.html");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("200", response->headers().find(":status")->second);
  // Connection headers are not valid in HTTP/2.
  EXPECT_FALSE(QuicContainsKey(response->headers(), "connection"));
  EXPECT_LT(0U, response->body().length());
}

TEST_F(QuicMemoryCacheBackendTest, DefaultResponse) {
  // Verify GetResponse returns nullptr when no default is set.
  const Response* response = cache_.GetResponse("www.google.com", "/");
  ASSERT_FALSE(response);

  // Add a default response.
  spdy::SpdyHeaderBlock response_headers;
  response_headers[":status"] = "200";
  response_headers["content-length"] = "0";
  Response* default_response = new Response;
  default_response->set_headers(std::move(response_headers));
  cache_.AddDefaultResponse(default_response);

  // Now we should get the default response for the original request.
  response = cache_.GetResponse("www.google.com", "/");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("200", response->headers().find(":status")->second);

  // Now add a set response for / and make sure it is returned
  cache_.AddSimpleResponse("www.google.com", "/", 302, "");
  response = cache_.GetResponse("www.google.com", "/");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("302", response->headers().find(":status")->second);

  // We should get the default response for other requests.
  response = cache_.GetResponse("www.google.com", "/asd");
  ASSERT_TRUE(response);
  ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
  EXPECT_EQ("200", response->headers().find(":status")->second);
}

TEST_F(QuicMemoryCacheBackendTest, AddSimpleResponseWithServerPushResources) {
  std::string request_host = "www.foo.com";
  std::string response_body("hello response");
  const size_t kNumResources = 5;
  int NumResources = 5;
  std::list<ServerPushInfo> push_resources;
  std::string scheme = "http";
  for (int i = 0; i < NumResources; ++i) {
    std::string path = "/server_push_src" + QuicTextUtils::Uint64ToString(i);
    std::string url = scheme + "://" + request_host + path;
    QuicUrl resource_url(url);
    std::string body =
        QuicStrCat("This is server push response body for ", path);
    spdy::SpdyHeaderBlock response_headers;
    response_headers[":status"] = "200";
    response_headers["content-length"] =
        QuicTextUtils::Uint64ToString(body.size());
    push_resources.push_back(
        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
  }

  cache_.AddSimpleResponseWithServerPushResources(
      request_host, "/", 200, response_body, push_resources);

  std::string request_url = request_host + "/";
  std::list<ServerPushInfo> resources =
      cache_.GetServerPushResources(request_url);
  ASSERT_EQ(kNumResources, resources.size());
  for (const auto& push_resource : push_resources) {
    ServerPushInfo resource = resources.front();
    EXPECT_EQ(resource.request_url.ToString(),
              push_resource.request_url.ToString());
    EXPECT_EQ(resource.priority, push_resource.priority);
    resources.pop_front();
  }
}

TEST_F(QuicMemoryCacheBackendTest, GetServerPushResourcesAndPushResponses) {
  std::string request_host = "www.foo.com";
  std::string response_body("hello response");
  const size_t kNumResources = 4;
  int NumResources = 4;
  std::string scheme = "http";
  std::string push_response_status[kNumResources] = {"200", "200", "301",
                                                     "404"};
  std::list<ServerPushInfo> push_resources;
  for (int i = 0; i < NumResources; ++i) {
    std::string path = "/server_push_src" + QuicTextUtils::Uint64ToString(i);
    std::string url = scheme + "://" + request_host + path;
    QuicUrl resource_url(url);
    std::string body = "This is server push response body for " + path;
    spdy::SpdyHeaderBlock response_headers;
    response_headers[":status"] = push_response_status[i];
    response_headers["content-length"] =
        QuicTextUtils::Uint64ToString(body.size());
    push_resources.push_back(
        ServerPushInfo(resource_url, response_headers.Clone(), i, body));
  }
  cache_.AddSimpleResponseWithServerPushResources(
      request_host, "/", 200, response_body, push_resources);
  std::string request_url = request_host + "/";
  std::list<ServerPushInfo> resources =
      cache_.GetServerPushResources(request_url);
  ASSERT_EQ(kNumResources, resources.size());
  int i = 0;
  for (const auto& push_resource : push_resources) {
    QuicUrl url = resources.front().request_url;
    std::string host = url.host();
    std::string path = url.path();
    const Response* response = cache_.GetResponse(host, path);
    ASSERT_TRUE(response);
    ASSERT_TRUE(QuicContainsKey(response->headers(), ":status"));
    EXPECT_EQ(push_response_status[i++],
              response->headers().find(":status")->second);
    EXPECT_EQ(push_resource.body, response->body());
    resources.pop_front();
  }
}

}  // namespace test
}  // namespace quic
