//===-- llvm/unittest/Support/HTTPServer.cpp - unit tests -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringExtras.h"
#include "llvm/Debuginfod/HTTPClient.h"
#include "llvm/Debuginfod/HTTPServer.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace llvm;

#ifdef LLVM_ENABLE_HTTPLIB

TEST(HTTPServer, IsAvailable) { EXPECT_TRUE(HTTPServer::isAvailable()); }

HTTPResponse Response = {200u, "text/plain", "hello, world\n"};
std::string UrlPathPattern = R"(/(.*))";
std::string InvalidUrlPathPattern = R"(/(.*)";

HTTPRequestHandler Handler = [](HTTPServerRequest &Request) {
  Request.setResponse(Response);
};

HTTPRequestHandler DelayHandler = [](HTTPServerRequest &Request) {
  std::this_thread::sleep_for(std::chrono::milliseconds(50));
  Request.setResponse(Response);
};

HTTPRequestHandler StreamingHandler = [](HTTPServerRequest &Request) {
  Request.setResponse({200, "text/plain", Response.Body.size(),
                       [=](size_t Offset, size_t Length) -> StringRef {
                         return Response.Body.substr(Offset, Length);
                       }});
};

TEST(HTTPServer, InvalidUrlPath) {
  // test that we can bind to any address
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(InvalidUrlPathPattern, Handler),
                    Failed<StringError>());
  EXPECT_THAT_EXPECTED(Server.bind(), Succeeded());
}

TEST(HTTPServer, bind) {
  // test that we can bind to any address
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, Handler), Succeeded());
  EXPECT_THAT_EXPECTED(Server.bind(), Succeeded());
}

TEST(HTTPServer, ListenBeforeBind) {
  // test that we can bind to any address
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, Handler), Succeeded());
  EXPECT_THAT_ERROR(Server.listen(), Failed<StringError>());
}

#ifdef LLVM_ENABLE_CURL
// Test the client and server against each other.

// Test fixture to initialize and teardown the HTTP client for each
// client-server test
class HTTPClientServerTest : public ::testing::Test {
protected:
  void SetUp() override { HTTPClient::initialize(); }
  void TearDown() override { HTTPClient::cleanup(); }
};

/// A simple handler which writes returned data to a string.
struct StringHTTPResponseHandler final : public HTTPResponseHandler {
  std::string ResponseBody = "";
  /// These callbacks store the body and status code in an HTTPResponseBuffer
  /// allocated based on Content-Length. The Content-Length header must be
  /// handled by handleHeaderLine before any calls to handleBodyChunk.
  Error handleBodyChunk(StringRef BodyChunk) override {
    ResponseBody = ResponseBody + BodyChunk.str();
    return Error::success();
  }
};

TEST_F(HTTPClientServerTest, Hello) {
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, Handler), Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, Response.Body);
  EXPECT_EQ(Client.responseCode(), Response.Code);
  Server.stop();
}

TEST_F(HTTPClientServerTest, LambdaHandlerHello) {
  HTTPServer Server;
  HTTPResponse LambdaResponse = {200u, "text/plain",
                                 "hello, world from a lambda\n"};
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern,
                               [LambdaResponse](HTTPServerRequest &Request) {
                                 Request.setResponse(LambdaResponse);
                               }),
                    Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, LambdaResponse.Body);
  EXPECT_EQ(Client.responseCode(), LambdaResponse.Code);
  Server.stop();
}

// Test the streaming response.
TEST_F(HTTPClientServerTest, StreamingHello) {
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, StreamingHandler), Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, Response.Body);
  EXPECT_EQ(Client.responseCode(), Response.Code);
  Server.stop();
}

// Writes a temporary file and streams it back using streamFile.
HTTPRequestHandler TempFileStreamingHandler = [](HTTPServerRequest Request) {
  int FD;
  SmallString<64> TempFilePath;
  sys::fs::createTemporaryFile("http-stream-file-test", "temp", FD,
                               TempFilePath);
  raw_fd_ostream OS(FD, true, /*unbuffered=*/true);
  OS << Response.Body;
  OS.close();
  streamFile(Request, TempFilePath);
};

// Test streaming back chunks of a file.
TEST_F(HTTPClientServerTest, StreamingFileResponse) {
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, TempFileStreamingHandler),
                    Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, Response.Body);
  EXPECT_EQ(Client.responseCode(), Response.Code);
  Server.stop();
}

// Deletes the temporary file before streaming it back, should give a 404 not
// found status code.
HTTPRequestHandler MissingTempFileStreamingHandler =
    [](HTTPServerRequest Request) {
      int FD;
      SmallString<64> TempFilePath;
      sys::fs::createTemporaryFile("http-stream-file-test", "temp", FD,
                                   TempFilePath);
      raw_fd_ostream OS(FD, true, /*unbuffered=*/true);
      OS << Response.Body;
      OS.close();
      // delete the file
      sys::fs::remove(TempFilePath);
      streamFile(Request, TempFilePath);
    };

// Streaming a missing file should give a 404.
TEST_F(HTTPClientServerTest, StreamingMissingFileResponse) {
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, MissingTempFileStreamingHandler),
                    Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Client.responseCode(), 404u);
  Server.stop();
}

TEST_F(HTTPClientServerTest, ClientTimeout) {
  HTTPServer Server;
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern, DelayHandler), Succeeded());
  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port);
  HTTPClient Client;
  // Timeout below 50ms, request should fail
  Client.setTimeout(std::chrono::milliseconds(40));
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Failed<StringError>());
  Server.stop();
}

// Check that Url paths are dispatched to the first matching handler and provide
// the correct path pattern match components.
TEST_F(HTTPClientServerTest, PathMatching) {
  HTTPServer Server;

  EXPECT_THAT_ERROR(
      Server.get(R"(/abc/(.*)/(.*))",
                 [&](HTTPServerRequest &Request) {
                   EXPECT_EQ(Request.UrlPath, "/abc/1/2");
                   ASSERT_THAT(Request.UrlPathMatches,
                               testing::ElementsAre("1", "2"));
                   Request.setResponse({200u, "text/plain", Request.UrlPath});
                 }),
      Succeeded());
  EXPECT_THAT_ERROR(Server.get(UrlPathPattern,
                               [&](HTTPServerRequest &Request) {
                                 llvm_unreachable(
                                     "Should not reach this handler");
                                 Handler(Request);
                               }),
                    Succeeded());

  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port) + "/abc/1/2";
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, "/abc/1/2");
  EXPECT_EQ(Client.responseCode(), 200u);
  Server.stop();
}

TEST_F(HTTPClientServerTest, FirstPathMatched) {
  HTTPServer Server;

  EXPECT_THAT_ERROR(
      Server.get(UrlPathPattern,
                 [&](HTTPServerRequest Request) { Handler(Request); }),
      Succeeded());

  EXPECT_THAT_ERROR(
      Server.get(R"(/abc/(.*)/(.*))",
                 [&](HTTPServerRequest Request) {
                   EXPECT_EQ(Request.UrlPathMatches.size(), 2u);
                   llvm_unreachable("Should not reach this handler");
                   Request.setResponse({200u, "text/plain", Request.UrlPath});
                 }),
      Succeeded());

  Expected<unsigned> PortOrErr = Server.bind();
  EXPECT_THAT_EXPECTED(PortOrErr, Succeeded());
  unsigned Port = *PortOrErr;
  ThreadPool Pool(hardware_concurrency(1));
  Pool.async([&]() { EXPECT_THAT_ERROR(Server.listen(), Succeeded()); });
  std::string Url = "http://localhost:" + utostr(Port) + "/abc/1/2";
  HTTPRequest Request(Url);
  StringHTTPResponseHandler Handler;
  HTTPClient Client;
  EXPECT_THAT_ERROR(Client.perform(Request, Handler), Succeeded());
  EXPECT_EQ(Handler.ResponseBody, Response.Body);
  EXPECT_EQ(Client.responseCode(), Response.Code);
  Server.stop();
}

#endif

#else

TEST(HTTPServer, IsAvailable) { EXPECT_FALSE(HTTPServer::isAvailable()); }

#endif // LLVM_ENABLE_HTTPLIB
