// 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 <gtest/gtest.h>

#include "buffet/bind_lambda.h"
#include "buffet/http_utils.h"
#include "buffet/http_transport_fake.h"
#include "buffet/mime_utils.h"
#include "buffet/string_utils.h"
#include "buffet/url_utils.h"

using namespace chromeos;        // NOLINT(build/namespaces)
using namespace chromeos::http;  // NOLINT(build/namespaces)

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).c_str());
};

// 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(), 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<unsigned char> custom_data({0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F});
  auto response = http::SendRequest(request_type::kPost, kEchoUrl,
                                    custom_data.data(), custom_data.size(),
                                    mime::application::kOctet_stream,
                                    HeaderList(), transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::application::kOctet_stream, response->GetContentType());
  EXPECT_EQ(custom_data.size(), response->GetData().size());
  EXPECT_EQ(custom_data, response->GetData());
}

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<unsigned char> custom_data({0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F});

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

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

  auto response = http::SendRequest(request_type::kGet, kMethodEchoUrl,
                                    nullptr, 0, nullptr,
                                    HeaderList(), transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kGet, response->GetDataAsString());
}

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

  auto response = http::SendRequest(request_type::kPut, kMethodEchoUrl,
                                    nullptr, 0, nullptr,
                                    HeaderList(), transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kPut, response->GetDataAsString());
}

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

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 (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::SendRequest(
      request_type::kPost, json_echo_url, "abcd", 4,
      mime::application::kOctet_stream, {
        {request_header::kCookie, "flavor=vanilla"},
        {request_header::kIfMatch, "*"},
      }, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::application::kJson,
            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(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"),
                        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/GetAsString actually do the GET request
  auto response = http::Get(kMethodEchoUrl, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(request_type::kGet, response->GetDataAsString());
  EXPECT_EQ(request_type::kGet,
            http::GetAsString(kMethodEchoUrl, transport, nullptr));

  for (std::string data : {"blah", "some data", ""}) {
    std::string url = url::AppendQueryParam(kFakeUrl, "test", data);
    EXPECT_EQ(data, http::GetAsString(url, transport, nullptr));
  }
}

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",
                        mime::text::kPlain);
  };

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

  auto response = http::Head(kFakeUrl, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
  EXPECT_EQ("", response->GetDataAsString());  // 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(mime::application::kOctet_stream,
              request.GetHeader(request_header::kContentType));
    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, "", 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<unsigned char> data(256);
  unsigned char counter = 0xFF;
  std::generate(data.begin(), data.end(), [&counter]() { return ++counter; });

  auto response = http::PostBinary(kFakeUrl, data.data(), data.size(),
                                   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(mime::text::kPlain,
              request.GetHeader(request_header::kContentType));
    response->ReplyText(status_code::Ok, request.GetDataAsString(),
                       mime::text::kPlain);
  };

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

  auto response = http::PostText(kFakeUrl, fake_data.c_str(),
                                 mime::text::kPlain, transport, nullptr);
  EXPECT_TRUE(response->IsSuccessful());
  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
  EXPECT_EQ(fake_data, response->GetDataAsString());
}

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

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

TEST(HttpUtils, PostPatchJson) {
  auto JsonHandler = [](const fake::ServerRequest& request,
                        fake::ServerResponse* response) {
    auto mime_type = mime::RemoveParameters(
        request.GetHeader(request_header::kContentType));
    EXPECT_EQ(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::PostJson(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::PatchJson(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 = string_utils::SplitAtFirst(item, ';');
    auto response = http::PostFormData(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, std::to_string(code));
    EXPECT_EQ(pair.second, value);
  }

  // Test invalid (non-JSON) response.
  auto response = http::Get("http://bad.url", transport, nullptr);
  EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
  EXPECT_EQ(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);
}

