// Copyright 2014 The Chromium OS 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 <numeric>
#include <string>
#include <vector>

#include <base/values.h>
#include <brillo/bind_lambda.h>
#include <brillo/http/http_transport_fake.h>
#include <brillo/http/http_utils.h>
#include <brillo/mime_utils.h>
#include <brillo/strings/string_utils.h>
#include <brillo/url_utils.h>
#include <gtest/gtest.h>

namespace brillo {
namespace http {

static const char kFakeUrl[] = "http://localhost";
static const char kEchoUrl[] = "http://localhost/echo";
static const char kMethodEchoUrl[] = "http://localhost/echo/method";

///////////////////// Generic helper request handlers /////////////////////////
// Returns the request data back with the same content type.
static void EchoDataHandler(const fake::ServerRequest& request,
                            fake::ServerResponse* response) {
  response->Reply(status_code::Ok,
                  request.GetData(),
                  request.GetHeader(request_header::kContentType));
}

// Returns the request method as a plain text response.
static void EchoMethodHandler(const fake::ServerRequest& request,
                              fake::ServerResponse* response) {
  response->ReplyText(
      status_code::Ok, request.GetMethod(), brillo::mime::text::kPlain);
}

///////////////////////////////////////////////////////////////////////////////
TEST(HttpUtils, SendRequest_BinaryData) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(
      kEchoUrl, request_type::kPost, base::Bind(EchoDataHandler));

  // Test binary data round-tripping.
  std::vector<uint8_t> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};
  auto response =
      http::SendRequestAndBlock(request_type::kPost,
                                kEchoUrl,
                                custom_data.data(),
                                custom_data.size(),
                                brillo::mime::application::kOctet_stream,
                                {},
                                transport,
                                nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::application::kOctet_stream,
            response->GetContentType());
  EXPECT_EQ(custom_data, response->ExtractData());
}

TEST(HttpUtils, SendRequestAsync_BinaryData) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(
      kEchoUrl, request_type::kPost, base::Bind(EchoDataHandler));

  // Test binary data round-tripping.
  std::vector<uint8_t> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};
  auto success_callback = [](const std::vector<uint8_t>& custom_data,
                             RequestID /* id */,
                             std::unique_ptr<http::Response> response) {
    EXPECT_TRUE(response->IsSuccessful());
    EXPECT_EQ(brillo::mime::application::kOctet_stream,
              response->GetContentType());
    EXPECT_EQ(custom_data, response->ExtractData());
  };
  auto error_callback = [](RequestID /* id */, const Error* /* error */) {
    FAIL() << "This callback shouldn't have been called";
  };
  http::SendRequest(request_type::kPost,
                    kEchoUrl,
                    custom_data.data(),
                    custom_data.size(),
                    brillo::mime::application::kOctet_stream,
                    {},
                    transport,
                    base::Bind(success_callback, custom_data),
                    base::Bind(error_callback));
}

TEST(HttpUtils, SendRequest_Post) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));

  // Test binary data round-tripping.
  std::vector<uint8_t> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};

  // Check the correct HTTP method used.
  auto response =
      http::SendRequestAndBlock(request_type::kPost,
                                kMethodEchoUrl,
                                custom_data.data(),
                                custom_data.size(),
                                brillo::mime::application::kOctet_stream,
                                {},
                                transport,
                                nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kPost, response->ExtractDataAsString());
}

TEST(HttpUtils, SendRequest_Get) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));

  auto response = http::SendRequestAndBlock(request_type::kGet,
                                            kMethodEchoUrl,
                                            nullptr,
                                            0,
                                            std::string{},
                                            {},
                                            transport,
                                            nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kGet, response->ExtractDataAsString());
}

TEST(HttpUtils, SendRequest_Put) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));

  auto response = http::SendRequestAndBlock(request_type::kPut,
                                            kMethodEchoUrl,
                                            nullptr,
                                            0,
                                            std::string{},
                                            {},
                                            transport,
                                            nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kPut, response->ExtractDataAsString());
}

TEST(HttpUtils, SendRequest_NotFound) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  // Test failed response (URL not found).
  auto response = http::SendRequestWithNoDataAndBlock(
      request_type::kGet, "http://blah.com", {}, transport, nullptr);
  EXPECT_FALSE(response->IsSuccessful());
  EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
}

TEST(HttpUtils, SendRequestAsync_NotFound) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  // Test failed response (URL not found).
  auto success_callback =
      [](RequestID /* request_id */, std::unique_ptr<http::Response> response) {
    EXPECT_FALSE(response->IsSuccessful());
    EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
  };
  auto error_callback = [](RequestID /* request_id */,
                           const Error* /* error */) {
    FAIL() << "This callback shouldn't have been called";
  };
  http::SendRequestWithNoData(request_type::kGet,
                              "http://blah.com",
                              {},
                              transport,
                              base::Bind(success_callback),
                              base::Bind(error_callback));
}

TEST(HttpUtils, SendRequest_Headers) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);

  static const char json_echo_url[] = "http://localhost/echo/json";
  auto JsonEchoHandler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    base::DictionaryValue json;
    json.SetString("method", request.GetMethod());
    json.SetString("data", request.GetDataAsString());
    for (const auto& pair : request.GetHeaders()) {
      json.SetString("header." + pair.first, pair.second);
    }
    response->ReplyJson(status_code::Ok, &json);
  };
  transport->AddHandler(json_echo_url, "*", base::Bind(JsonEchoHandler));
  auto response = http::SendRequestAndBlock(
      request_type::kPost, json_echo_url, "abcd", 4,
      brillo::mime::application::kOctet_stream, {
        {request_header::kCookie, "flavor=vanilla"},
        {request_header::kIfMatch, "*"},
      }, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::application::kJson,
            brillo::mime::RemoveParameters(response->GetContentType()));
  auto json = ParseJsonResponse(response.get(), nullptr, nullptr);
  std::string value;
  EXPECT_TRUE(json->GetString("method", &value));
  EXPECT_EQ(request_type::kPost, value);
  EXPECT_TRUE(json->GetString("data", &value));
  EXPECT_EQ("abcd", value);
  EXPECT_TRUE(json->GetString("header.Cookie", &value));
  EXPECT_EQ("flavor=vanilla", value);
  EXPECT_TRUE(json->GetString("header.Content-Type", &value));
  EXPECT_EQ(brillo::mime::application::kOctet_stream, value);
  EXPECT_TRUE(json->GetString("header.Content-Length", &value));
  EXPECT_EQ("4", value);
  EXPECT_TRUE(json->GetString("header.If-Match", &value));
  EXPECT_EQ("*", value);
}

TEST(HttpUtils, Get) {
  // Sends back the "?test=..." portion of URL.
  // So if we do GET "http://localhost?test=blah", this handler responds
  // with "blah" as text/plain.
  auto GetHandler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    EXPECT_EQ(request_type::kGet, request.GetMethod());
    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
    response->ReplyText(status_code::Ok,
                        request.GetFormField("test"),
                        brillo::mime::text::kPlain);
  };

  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kFakeUrl, request_type::kGet, base::Bind(GetHandler));
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));

  // Make sure Get() actually does the GET request
  auto response = http::GetAndBlock(kMethodEchoUrl, {}, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kGet, response->ExtractDataAsString());

  for (std::string data : {"blah", "some data", ""}) {
    std::string url = brillo::url::AppendQueryParam(kFakeUrl, "test", data);
    response = http::GetAndBlock(url, {}, transport, nullptr);
    EXPECT_EQ(data, response->ExtractDataAsString());
  }
}

TEST(HttpUtils, Head) {
  auto HeadHandler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    EXPECT_EQ(request_type::kHead, request.GetMethod());
    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
    response->ReplyText(status_code::Ok, "blah", brillo::mime::text::kPlain);
  };

  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kFakeUrl, request_type::kHead, base::Bind(HeadHandler));

  auto response = http::HeadAndBlock(kFakeUrl, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ("", response->ExtractDataAsString());  // Must not have actual body.
  EXPECT_EQ("4", response->GetHeader(request_header::kContentLength));
}

TEST(HttpUtils, PostBinary) {
  auto Handler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    EXPECT_EQ(request_type::kPost, request.GetMethod());
    EXPECT_EQ("256", request.GetHeader(request_header::kContentLength));
    EXPECT_EQ(brillo::mime::application::kOctet_stream,
              request.GetHeader(request_header::kContentType));
    const auto& data = request.GetData();
    EXPECT_EQ(256, data.size());

    // Sum up all the bytes.
    int sum = std::accumulate(data.begin(), data.end(), 0);
    EXPECT_EQ(32640, sum);  // sum(i, i => [0, 255]) = 32640.
    response->ReplyText(status_code::Ok, "", brillo::mime::text::kPlain);
  };

  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(Handler));

  /// Fill the data buffer with bytes from 0x00 to 0xFF.
  std::vector<uint8_t> data(256);
  std::iota(data.begin(), data.end(), 0);

  auto response = http::PostBinaryAndBlock(kFakeUrl,
                                           data.data(),
                                           data.size(),
                                           mime::application::kOctet_stream,
                                           {},
                                           transport,
                                           nullptr);
  EXPECT_TRUE(response->IsSuccessful());
}

TEST(HttpUtils, PostText) {
  std::string fake_data = "Some data";
  auto PostHandler = [](const std::string& fake_data,
                        const fake::ServerRequest& request,
                        fake::ServerResponse* response) {
    EXPECT_EQ(request_type::kPost, request.GetMethod());
    EXPECT_EQ(fake_data.size(),
              std::stoul(request.GetHeader(request_header::kContentLength)));
    EXPECT_EQ(brillo::mime::text::kPlain,
              request.GetHeader(request_header::kContentType));
    response->ReplyText(status_code::Ok,
                        request.GetDataAsString(),
                        brillo::mime::text::kPlain);
  };

  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(
      kFakeUrl, request_type::kPost, base::Bind(PostHandler, fake_data));

  auto response = http::PostTextAndBlock(kFakeUrl,
                                         fake_data,
                                         brillo::mime::text::kPlain,
                                         {},
                                         transport,
                                         nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(fake_data, response->ExtractDataAsString());
}

TEST(HttpUtils, PostFormData) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(
      kFakeUrl, request_type::kPost, base::Bind(EchoDataHandler));

  auto response = http::PostFormDataAndBlock(
      kFakeUrl, {
          {"key", "value"},
          {"field", "field value"},
      }, {}, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(brillo::mime::application::kWwwFormUrlEncoded,
            response->GetContentType());
  EXPECT_EQ("key=value&field=field+value", response->ExtractDataAsString());
}

TEST(HttpUtils, PostMultipartFormData) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(
      kFakeUrl, request_type::kPost, base::Bind(EchoDataHandler));

  std::unique_ptr<FormData> form_data{new FormData{"boundary123"}};
  form_data->AddTextField("key1", "value1");
  form_data->AddTextField("key2", "value2");
  std::string expected_content_type = form_data->GetContentType();
  auto response = http::PostFormDataAndBlock(
      kFakeUrl, std::move(form_data), {}, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(expected_content_type, response->GetContentType());
  const char expected_value[] =
      "--boundary123\r\n"
      "Content-Disposition: form-data; name=\"key1\"\r\n"
      "\r\n"
      "value1\r\n"
      "--boundary123\r\n"
      "Content-Disposition: form-data; name=\"key2\"\r\n"
      "\r\n"
      "value2\r\n"
      "--boundary123--";
  EXPECT_EQ(expected_value, response->ExtractDataAsString());
}

TEST(HttpUtils, PostPatchJson) {
  auto JsonHandler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    auto mime_type = brillo::mime::RemoveParameters(
        request.GetHeader(request_header::kContentType));
    EXPECT_EQ(brillo::mime::application::kJson, mime_type);
    response->ReplyJson(
        status_code::Ok,
        {
          {"method", request.GetMethod()}, {"data", request.GetDataAsString()},
        });
  };
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kFakeUrl, "*", base::Bind(JsonHandler));

  base::DictionaryValue json;
  json.SetString("key1", "val1");
  json.SetString("key2", "val2");
  std::string value;

  // Test POST
  auto response =
      http::PostJsonAndBlock(kFakeUrl, &json, {}, transport, nullptr);
  auto resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr);
  EXPECT_NE(nullptr, resp_json.get());
  EXPECT_TRUE(resp_json->GetString("method", &value));
  EXPECT_EQ(request_type::kPost, value);
  EXPECT_TRUE(resp_json->GetString("data", &value));
  EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value);

  // Test PATCH
  response = http::PatchJsonAndBlock(kFakeUrl, &json, {}, transport, nullptr);
  resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr);
  EXPECT_NE(nullptr, resp_json.get());
  EXPECT_TRUE(resp_json->GetString("method", &value));
  EXPECT_EQ(request_type::kPatch, value);
  EXPECT_TRUE(resp_json->GetString("data", &value));
  EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value);
}

TEST(HttpUtils, ParseJsonResponse) {
  auto JsonHandler =
      [](const fake::ServerRequest& request, fake::ServerResponse* response) {
    int status_code = std::stoi(request.GetFormField("code"));
    response->ReplyJson(status_code, {{"data", request.GetFormField("value")}});
  };
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(JsonHandler));

  // Test valid JSON responses (with success or error codes).
  for (auto item : {"200;data", "400;wrong", "500;Internal Server error"}) {
    auto pair = brillo::string_utils::SplitAtFirst(item, ";");
    auto response = http::PostFormDataAndBlock(
        kFakeUrl, {
          {"code", pair.first},
          {"value", pair.second},
        }, {}, transport, nullptr);
    int code = 0;
    auto json = http::ParseJsonResponse(response.get(), &code, nullptr);
    EXPECT_NE(nullptr, json.get());
    std::string value;
    EXPECT_TRUE(json->GetString("data", &value));
    EXPECT_EQ(pair.first, brillo::string_utils::ToString(code));
    EXPECT_EQ(pair.second, value);
  }

  // Test invalid (non-JSON) response.
  auto response = http::GetAndBlock("http://bad.url", {}, transport, nullptr);
  EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
  EXPECT_EQ(brillo::mime::text::kHtml, response->GetContentType());
  int code = 0;
  auto json = http::ParseJsonResponse(response.get(), &code, nullptr);
  EXPECT_EQ(nullptr, json.get());
  EXPECT_EQ(status_code::NotFound, code);
}

TEST(HttpUtils, SendRequest_Failure) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
  ErrorPtr error;
  Error::AddTo(&error, FROM_HERE, "test_domain", "test_code", "Test message");
  transport->SetCreateConnectionError(std::move(error));
  error.reset();  // Just to make sure it is empty...
  auto response = http::SendRequestWithNoDataAndBlock(
      request_type::kGet, "http://blah.com", {}, transport, &error);
  EXPECT_EQ(nullptr, response.get());
  EXPECT_EQ("test_domain", error->GetDomain());
  EXPECT_EQ("test_code", error->GetCode());
  EXPECT_EQ("Test message", error->GetMessage());
}

TEST(HttpUtils, SendRequestAsync_Failure) {
  std::shared_ptr<fake::Transport> transport(new fake::Transport);
  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
  ErrorPtr error;
  Error::AddTo(&error, FROM_HERE, "test_domain", "test_code", "Test message");
  transport->SetCreateConnectionError(std::move(error));
  auto success_callback =
      [](RequestID /* request_id */,
         std::unique_ptr<http::Response> /* response */) {
    FAIL() << "This callback shouldn't have been called";
  };
  auto error_callback = [](RequestID /* request_id */, const Error* error) {
    EXPECT_EQ("test_domain", error->GetDomain());
    EXPECT_EQ("test_code", error->GetCode());
    EXPECT_EQ("Test message", error->GetMessage());
  };
  http::SendRequestWithNoData(request_type::kGet,
                              "http://blah.com",
                              {},
                              transport,
                              base::Bind(success_callback),
                              base::Bind(error_callback));
}

TEST(HttpUtils, GetCanonicalHeaderName) {
  EXPECT_EQ("Foo", GetCanonicalHeaderName("foo"));
  EXPECT_EQ("Bar", GetCanonicalHeaderName("BaR"));
  EXPECT_EQ("Baz", GetCanonicalHeaderName("BAZ"));
  EXPECT_EQ("Foo-Bar", GetCanonicalHeaderName("foo-bar"));
  EXPECT_EQ("Foo-Bar-Baz", GetCanonicalHeaderName("foo-Bar-BAZ"));
  EXPECT_EQ("Foo-Bar-Baz", GetCanonicalHeaderName("FOO-BAR-BAZ"));
  EXPECT_EQ("Foo-Bar-", GetCanonicalHeaderName("fOO-bAR-"));
  EXPECT_EQ("-Bar", GetCanonicalHeaderName("-bAR"));
  EXPECT_EQ("", GetCanonicalHeaderName(""));
  EXPECT_EQ("A-B-C", GetCanonicalHeaderName("a-B-c"));
}

}  // namespace http
}  // namespace brillo
