// 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_transport_fake.h"
#include "buffet/http_utils.h"
#include "buffet/mime_utils.h"
#include "buffet/string_utils.h"
#include "buffet/url_utils.h"

using namespace buffet;        // NOLINT(build/namespaces)
using namespace buffet::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 (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::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));
    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, "", 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);
  std::iota(data.begin(), data.end(), 0);

  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, string_utils::ToString(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);
}

