// 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 <string>
#include <vector>

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

namespace chromeos {
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(), chromeos::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(),
                                chromeos::mime::application::kOctet_stream,
                                {},
                                transport,
                                nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(chromeos::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 =
      [&custom_data](RequestID id, std::unique_ptr<http::Response> response) {
    EXPECT_TRUE(response->IsSuccessful());
    EXPECT_EQ(chromeos::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(),
                    chromeos::mime::application::kOctet_stream,
                    {},
                    transport,
                    base::Bind(success_callback),
                    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(),
                                chromeos::mime::application::kOctet_stream,
                                {},
                                transport,
                                nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(chromeos::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(chromeos::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(chromeos::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,
      chromeos::mime::application::kOctet_stream, {
        {request_header::kCookie, "flavor=vanilla"},
        {request_header::kIfMatch, "*"},
      }, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(chromeos::mime::application::kJson,
            chromeos::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(chromeos::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"),
                        chromeos::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(chromeos::mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kGet, response->ExtractDataAsString());

  for (std::string data : {"blah", "some data", ""}) {
    std::string url = chromeos::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", chromeos::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(chromeos::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(chromeos::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, "", chromeos::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 = [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(chromeos::mime::text::kPlain,
              request.GetHeader(request_header::kContentType));
    response->ReplyText(status_code::Ok,
                        request.GetDataAsString(),
                        chromeos::mime::text::kPlain);
  };

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

  auto response = http::PostTextAndBlock(kFakeUrl,
                                         fake_data,
                                         chromeos::mime::text::kPlain,
                                         {},
                                         transport,
                                         nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(chromeos::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(chromeos::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 = chromeos::mime::RemoveParameters(
        request.GetHeader(request_header::kContentType));
    EXPECT_EQ(chromeos::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 = chromeos::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, chromeos::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(chromeos::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 chromeos
