//===--- HTTPClient.cpp - HTTP client library -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the implementation of the HTTPClient library for issuing
/// HTTP requests and handling the responses.
///
//===----------------------------------------------------------------------===//

#include "llvm/Support/HTTP/HTTPClient.h"

#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#ifdef LLVM_ENABLE_CURL
#include <curl/curl.h>
#endif
#ifdef _WIN32
#include "llvm/Support/ConvertUTF.h"
#endif

using namespace llvm;

HTTPRequest::HTTPRequest(StringRef Url) { this->Url = Url.str(); }

bool operator==(const HTTPRequest &A, const HTTPRequest &B) {
  return A.Url == B.Url && A.Method == B.Method &&
         A.FollowRedirects == B.FollowRedirects;
}

HTTPResponseHandler::~HTTPResponseHandler() = default;

bool HTTPClient::IsInitialized = false;

class HTTPClientCleanup {
public:
  ~HTTPClientCleanup() { HTTPClient::cleanup(); }
};
ManagedStatic<HTTPClientCleanup> Cleanup;

#ifdef LLVM_ENABLE_CURL

bool HTTPClient::isAvailable() { return true; }

void HTTPClient::initialize() {
  if (!IsInitialized) {
    curl_global_init(CURL_GLOBAL_ALL);
    IsInitialized = true;
  }
}

void HTTPClient::cleanup() {
  if (IsInitialized) {
    curl_global_cleanup();
    IsInitialized = false;
  }
}

void HTTPClient::setTimeout(std::chrono::milliseconds Timeout) {
  if (Timeout < std::chrono::milliseconds(0))
    Timeout = std::chrono::milliseconds(0);
  curl_easy_setopt(Handle, CURLOPT_TIMEOUT_MS, Timeout.count());
}

/// CurlHTTPRequest and the curl{Header,Write}Function are implementation
/// details used to work with Curl. Curl makes callbacks with a single
/// customizable pointer parameter.
struct CurlHTTPRequest {
  CurlHTTPRequest(HTTPResponseHandler &Handler) : Handler(Handler) {}
  void storeError(Error Err) {
    ErrorState = joinErrors(std::move(Err), std::move(ErrorState));
  }
  HTTPResponseHandler &Handler;
  llvm::Error ErrorState = Error::success();
};

static size_t curlWriteFunction(char *Contents, size_t Size, size_t NMemb,
                                CurlHTTPRequest *CurlRequest) {
  Size *= NMemb;
  if (Error Err =
          CurlRequest->Handler.handleBodyChunk(StringRef(Contents, Size))) {
    CurlRequest->storeError(std::move(Err));
    return 0;
  }
  return Size;
}

HTTPClient::HTTPClient() {
  assert(IsInitialized &&
         "Must call HTTPClient::initialize() at the beginning of main().");
  if (Handle)
    return;
  Handle = curl_easy_init();
  assert(Handle && "Curl could not be initialized");
  // Set the callback hooks.
  curl_easy_setopt(Handle, CURLOPT_WRITEFUNCTION, curlWriteFunction);
  // Detect supported compressed encodings and accept all.
  curl_easy_setopt(Handle, CURLOPT_ACCEPT_ENCODING, "");
}

HTTPClient::~HTTPClient() { curl_easy_cleanup(Handle); }

Error HTTPClient::perform(const HTTPRequest &Request,
                          HTTPResponseHandler &Handler) {
  if (Request.Method != HTTPMethod::GET)
    return createStringError(errc::invalid_argument,
                             "Unsupported CURL request method.");

  SmallString<128> Url = Request.Url;
  curl_easy_setopt(Handle, CURLOPT_URL, Url.c_str());
  curl_easy_setopt(Handle, CURLOPT_FOLLOWLOCATION, Request.FollowRedirects);

  curl_slist *Headers = nullptr;
  for (const std::string &Header : Request.Headers)
    Headers = curl_slist_append(Headers, Header.c_str());
  curl_easy_setopt(Handle, CURLOPT_HTTPHEADER, Headers);

  CurlHTTPRequest CurlRequest(Handler);
  curl_easy_setopt(Handle, CURLOPT_WRITEDATA, &CurlRequest);
  CURLcode CurlRes = curl_easy_perform(Handle);
  curl_slist_free_all(Headers);
  if (CurlRes != CURLE_OK)
    return joinErrors(std::move(CurlRequest.ErrorState),
                      createStringError(errc::io_error,
                                        "curl_easy_perform() failed: %s\n",
                                        curl_easy_strerror(CurlRes)));
  return std::move(CurlRequest.ErrorState);
}

unsigned HTTPClient::responseCode() {
  long Code = 0;
  curl_easy_getinfo(Handle, CURLINFO_RESPONSE_CODE, &Code);
  return Code;
}

#else

#ifdef _WIN32
#include <windows.h>
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")

namespace {

struct WinHTTPSession {
  HINTERNET SessionHandle = nullptr;
  HINTERNET ConnectHandle = nullptr;
  HINTERNET RequestHandle = nullptr;
  DWORD ResponseCode = 0;

  ~WinHTTPSession() {
    if (RequestHandle)
      WinHttpCloseHandle(RequestHandle);
    if (ConnectHandle)
      WinHttpCloseHandle(ConnectHandle);
    if (SessionHandle)
      WinHttpCloseHandle(SessionHandle);
  }
};

bool parseURL(StringRef Url, std::wstring &Host, std::wstring &Path,
              INTERNET_PORT &Port, bool &Secure) {
  // Parse URL: http://host:port/path
  if (Url.starts_with("https://")) {
    Secure = true;
    Url = Url.drop_front(8);
  } else if (Url.starts_with("http://")) {
    Secure = false;
    Url = Url.drop_front(7);
  } else {
    return false;
  }

  size_t SlashPos = Url.find('/');
  StringRef HostPort =
      (SlashPos != StringRef::npos) ? Url.substr(0, SlashPos) : Url;
  StringRef PathPart =
      (SlashPos != StringRef::npos) ? Url.substr(SlashPos) : StringRef("/");

  size_t ColonPos = HostPort.find(':');
  StringRef HostStr =
      (ColonPos != StringRef::npos) ? HostPort.substr(0, ColonPos) : HostPort;

  if (!llvm::ConvertUTF8toWide(HostStr, Host))
    return false;
  if (!llvm::ConvertUTF8toWide(PathPart, Path))
    return false;

  if (ColonPos != StringRef::npos) {
    StringRef PortStr = HostPort.substr(ColonPos + 1);
    Port = static_cast<INTERNET_PORT>(std::stoi(PortStr.str()));
  } else {
    Port = Secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
  }

  return true;
}

} // namespace

HTTPClient::HTTPClient() : Handle(new WinHTTPSession()) {}

HTTPClient::~HTTPClient() { delete static_cast<WinHTTPSession *>(Handle); }

bool HTTPClient::isAvailable() { return true; }

void HTTPClient::initialize() {
  if (!IsInitialized) {
    IsInitialized = true;
  }
}

void HTTPClient::cleanup() {
  if (IsInitialized) {
    IsInitialized = false;
  }
}

void HTTPClient::setTimeout(std::chrono::milliseconds Timeout) {
  WinHTTPSession *Session = static_cast<WinHTTPSession *>(Handle);
  if (Session && Session->SessionHandle) {
    DWORD TimeoutMs = static_cast<DWORD>(Timeout.count());
    WinHttpSetOption(Session->SessionHandle, WINHTTP_OPTION_CONNECT_TIMEOUT,
                     &TimeoutMs, sizeof(TimeoutMs));
    WinHttpSetOption(Session->SessionHandle, WINHTTP_OPTION_RECEIVE_TIMEOUT,
                     &TimeoutMs, sizeof(TimeoutMs));
    WinHttpSetOption(Session->SessionHandle, WINHTTP_OPTION_SEND_TIMEOUT,
                     &TimeoutMs, sizeof(TimeoutMs));
  }
}

Error HTTPClient::perform(const HTTPRequest &Request,
                          HTTPResponseHandler &Handler) {
  if (Request.Method != HTTPMethod::GET)
    return createStringError(errc::invalid_argument,
                             "Only GET requests are supported.");
  for (const std::string &Header : Request.Headers)
    if (Header.find("\r") != std::string::npos ||
        Header.find("\n") != std::string::npos) {
      return createStringError(errc::invalid_argument,
                               "Unsafe request can lead to header injection.");
    }

  WinHTTPSession *Session = static_cast<WinHTTPSession *>(Handle);

  // Parse URL
  std::wstring Host, Path;
  INTERNET_PORT Port = 0;
  bool Secure = false;
  if (!parseURL(Request.Url, Host, Path, Port, Secure))
    return createStringError(errc::invalid_argument,
                             "Invalid URL: " + Request.Url);

  // Create session
  Session->SessionHandle =
      WinHttpOpen(L"LLVM-HTTPClient/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                  WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
  if (!Session->SessionHandle)
    return createStringError(errc::io_error, "Failed to open WinHTTP session");

  // Prevent fallback to TLS 1.0/1.1
  DWORD SecureProtocols =
      WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3;
  if (!WinHttpSetOption(Session->SessionHandle, WINHTTP_OPTION_SECURE_PROTOCOLS,
                        &SecureProtocols, sizeof(SecureProtocols)))
    return createStringError(errc::io_error, "Failed to set secure protocols");

  // Use HTTP/2 if available
  DWORD EnableHttp2 = WINHTTP_PROTOCOL_FLAG_HTTP2;
  WinHttpSetOption(Session->SessionHandle, WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL,
                   &EnableHttp2, sizeof(EnableHttp2));

  // Create connection
  Session->ConnectHandle =
      WinHttpConnect(Session->SessionHandle, Host.c_str(), Port, 0);
  if (!Session->ConnectHandle) {
    return createStringError(errc::io_error,
                             "Failed to connect to host: " + Request.Url);
  }

  // Open request
  DWORD Flags = WINHTTP_FLAG_REFRESH;
  if (Secure)
    Flags |= WINHTTP_FLAG_SECURE;

  Session->RequestHandle = WinHttpOpenRequest(
      Session->ConnectHandle, L"GET", Path.c_str(), nullptr, WINHTTP_NO_REFERER,
      WINHTTP_DEFAULT_ACCEPT_TYPES, Flags);
  if (!Session->RequestHandle)
    return createStringError(errc::io_error, "Failed to open HTTP request");

  // Enforce checks that certificate wasn't revoked.
  DWORD EnableRevocationChecks = WINHTTP_ENABLE_SSL_REVOCATION;
  if (!WinHttpSetOption(Session->RequestHandle, WINHTTP_OPTION_ENABLE_FEATURE,
                        &EnableRevocationChecks,
                        sizeof(EnableRevocationChecks)))
    return createStringError(errc::io_error,
                             "Failed to enable certificate revocation checks");

  // Explicitly enforce default validation. This protects against insecure
  // overrides like SECURITY_FLAG_IGNORE_UNKNOWN_CA.
  DWORD SecurityFlags = 0;
  if (!WinHttpSetOption(Session->RequestHandle, WINHTTP_OPTION_SECURITY_FLAGS,
                        &SecurityFlags, sizeof(SecurityFlags)))
    return createStringError(errc::io_error,
                             "Failed to enforce security flags");

  // Add headers
  for (const std::string &Header : Request.Headers) {
    std::wstring WideHeader;
    if (!llvm::ConvertUTF8toWide(Header, WideHeader))
      continue;
    WinHttpAddRequestHeaders(Session->RequestHandle, WideHeader.c_str(),
                             static_cast<DWORD>(WideHeader.length()),
                             WINHTTP_ADDREQ_FLAG_ADD);
  }

  // Send request
  if (!WinHttpSendRequest(Session->RequestHandle, WINHTTP_NO_ADDITIONAL_HEADERS,
                          0, nullptr, 0, 0, 0))
    return createStringError(errc::io_error, "Failed to send HTTP request");

  // Receive response
  if (!WinHttpReceiveResponse(Session->RequestHandle, nullptr))
    return createStringError(errc::io_error, "Failed to receive HTTP response");

  // Get response code
  DWORD CodeSize = sizeof(Session->ResponseCode);
  if (!WinHttpQueryHeaders(Session->RequestHandle,
                           WINHTTP_QUERY_STATUS_CODE |
                               WINHTTP_QUERY_FLAG_NUMBER,
                           WINHTTP_HEADER_NAME_BY_INDEX, &Session->ResponseCode,
                           &CodeSize, nullptr))
    Session->ResponseCode = 0;

  // Read response body
  DWORD BytesAvailable = 0;
  while (WinHttpQueryDataAvailable(Session->RequestHandle, &BytesAvailable)) {
    if (BytesAvailable == 0)
      break;

    std::vector<char> Buffer(BytesAvailable);
    DWORD BytesRead = 0;
    if (!WinHttpReadData(Session->RequestHandle, Buffer.data(), BytesAvailable,
                         &BytesRead))
      return createStringError(errc::io_error, "Failed to read HTTP response");

    if (BytesRead > 0) {
      if (Error Err =
              Handler.handleBodyChunk(StringRef(Buffer.data(), BytesRead)))
        return Err;
    }
  }

  return Error::success();
}

unsigned HTTPClient::responseCode() {
  WinHTTPSession *Session = static_cast<WinHTTPSession *>(Handle);
  return Session ? Session->ResponseCode : 0;
}

#else // _WIN32

// Non-Windows, non-libcurl stub implementations
HTTPClient::HTTPClient() = default;

HTTPClient::~HTTPClient() = default;

bool HTTPClient::isAvailable() { return false; }

void HTTPClient::initialize() {}

void HTTPClient::cleanup() {}

void HTTPClient::setTimeout(std::chrono::milliseconds Timeout) {}

Error HTTPClient::perform(const HTTPRequest &Request,
                          HTTPResponseHandler &Handler) {
  llvm_unreachable("No HTTP Client implementation available.");
}

unsigned HTTPClient::responseCode() {
  llvm_unreachable("No HTTP Client implementation available.");
}

#endif // _WIN32

#endif
