// 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 <brillo/http/http_request.h>

#include <string>

#include <base/bind.h>
#include <base/callback.h>
#include <brillo/http/mock_connection.h>
#include <brillo/http/mock_transport.h>
#include <brillo/mime_utils.h>
#include <brillo/streams/mock_stream.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::Return;
using testing::SetArgPointee;
using testing::Unused;
using testing::WithArg;

namespace brillo {
namespace http {

MATCHER_P(ContainsStringData, str, "") {
  if (arg->GetSize() != str.size())
    return false;

  std::string data;
  char buf[100];
  size_t read = 0;
  while (arg->ReadBlocking(buf, sizeof(buf), &read, nullptr) && read > 0) {
    data.append(buf, read);
  }
  return data == str;
}

class HttpRequestTest : public testing::Test {
 public:
  void SetUp() override {
    transport_ = std::make_shared<MockTransport>();
    connection_ = std::make_shared<MockConnection>(transport_);
  }

  void TearDown() override {
    // Having shared pointers to mock objects (some of methods in these tests
    // return shared pointers to connection and transport) could cause the
    // test expectations to hold on to the mock object without releasing them
    // at the end of a test, causing Mock's object leak detection to erroneously
    // detect mock object "leaks". Verify and clear the expectations manually
    // and explicitly to ensure the shared pointer refcounters are not
    // preventing the mocks to be destroyed at the end of each test.
    testing::Mock::VerifyAndClearExpectations(connection_.get());
    connection_.reset();
    testing::Mock::VerifyAndClearExpectations(transport_.get());
    transport_.reset();
  }

 protected:
  std::shared_ptr<MockTransport> transport_;
  std::shared_ptr<MockConnection> connection_;
};

TEST_F(HttpRequestTest, Defaults) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  EXPECT_TRUE(request.GetContentType().empty());
  EXPECT_TRUE(request.GetReferer().empty());
  EXPECT_TRUE(request.GetUserAgent().empty());
  EXPECT_EQ("*/*", request.GetAccept());
  EXPECT_EQ("http://www.foo.bar", request.GetRequestURL());
  EXPECT_EQ(request_type::kPost, request.GetRequestMethod());

  Request request2{"http://www.foo.bar/baz", request_type::kGet, transport_};
  EXPECT_EQ("http://www.foo.bar/baz", request2.GetRequestURL());
  EXPECT_EQ(request_type::kGet, request2.GetRequestMethod());
}

TEST_F(HttpRequestTest, ContentType) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  request.SetContentType(mime::image::kJpeg);
  EXPECT_EQ(mime::image::kJpeg, request.GetContentType());
}

TEST_F(HttpRequestTest, Referer) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  request.SetReferer("http://www.foo.bar/baz");
  EXPECT_EQ("http://www.foo.bar/baz", request.GetReferer());
}

TEST_F(HttpRequestTest, UserAgent) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  request.SetUserAgent("FooBar Browser");
  EXPECT_EQ("FooBar Browser", request.GetUserAgent());
}

TEST_F(HttpRequestTest, Accept) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  request.SetAccept("text/*, text/html, text/html;level=1, */*");
  EXPECT_EQ("text/*, text/html, text/html;level=1, */*", request.GetAccept());
}

TEST_F(HttpRequestTest, GetResponseAndBlock) {
  Request request{"http://www.foo.bar", request_type::kPost, transport_};
  request.SetUserAgent("FooBar Browser");
  request.SetReferer("http://www.foo.bar/baz");
  request.SetAccept("text/*, text/html, text/html;level=1, */*");
  request.AddHeader(request_header::kAcceptEncoding, "compress, gzip");
  request.AddHeaders({
      {request_header::kAcceptLanguage, "da, en-gb;q=0.8, en;q=0.7"},
      {request_header::kConnection, "close"},
  });
  request.AddRange(-10);
  request.AddRange(100, 200);
  request.AddRange(300);
  std::string req_body{"Foo bar baz"};
  request.AddHeader(request_header::kContentType, mime::text::kPlain);

  EXPECT_CALL(
      *transport_,
      CreateConnection(
          "http://www.foo.bar", request_type::kPost,
          HeaderList{
              {request_header::kAcceptEncoding, "compress, gzip"},
              {request_header::kAcceptLanguage, "da, en-gb;q=0.8, en;q=0.7"},
              {request_header::kConnection, "close"},
              {request_header::kContentType, mime::text::kPlain},
              {request_header::kRange, "bytes=-10,100-200,300-"},
              {request_header::kAccept,
               "text/*, text/html, text/html;level=1, */*"},
          },
          "FooBar Browser", "http://www.foo.bar/baz", nullptr))
      .WillOnce(Return(connection_));

  EXPECT_CALL(*connection_, MockSetRequestData(ContainsStringData(req_body), _))
      .WillOnce(Return(true));

  EXPECT_TRUE(
      request.AddRequestBody(req_body.data(), req_body.size(), nullptr));

  EXPECT_CALL(*connection_, FinishRequest(_)).WillOnce(Return(true));
  auto resp = request.GetResponseAndBlock(nullptr);
  EXPECT_NE(nullptr, resp.get());
}

TEST_F(HttpRequestTest, GetResponse) {
  Request request{"http://foo.bar", request_type::kGet, transport_};

  std::string resp_data{"FooBar response body"};
  auto read_data = [&resp_data](void* buffer, Unused, size_t* read,
                                Unused) -> bool {
    memcpy(buffer, resp_data.data(), resp_data.size());
    *read = resp_data.size();
    return true;
  };

  auto success_callback = base::Bind(
      [](MockConnection* connection, const std::string& resp_data,
         RequestID request_id, std::unique_ptr<Response> resp) {
        EXPECT_EQ(23, request_id);
        EXPECT_CALL(*connection, GetResponseStatusCode())
            .WillOnce(Return(status_code::Partial));
        EXPECT_EQ(status_code::Partial, resp->GetStatusCode());

        EXPECT_CALL(*connection, GetResponseStatusText())
            .WillOnce(Return("Partial completion"));
        EXPECT_EQ("Partial completion", resp->GetStatusText());

        EXPECT_CALL(*connection,
                    GetResponseHeader(response_header::kContentType))
            .WillOnce(Return(mime::text::kHtml));
        EXPECT_EQ(mime::text::kHtml, resp->GetContentType());

        EXPECT_EQ(resp_data, resp->ExtractDataAsString());
      },
      connection_.get(), resp_data);

  auto finish_request_async =
      [this, &read_data](const SuccessCallback& success_callback) {
        std::unique_ptr<MockStream> mock_stream{new MockStream};
        EXPECT_CALL(*mock_stream, ReadBlocking(_, _, _, _))
            .WillOnce(Invoke(read_data))
            .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));

        EXPECT_CALL(*connection_, MockExtractDataStream(_))
            .WillOnce(Return(mock_stream.release()));
        std::unique_ptr<Response> resp{new Response{connection_}};
        success_callback.Run(23, std::move(resp));
      };

  EXPECT_CALL(*transport_, CreateConnection("http://foo.bar",
                                            request_type::kGet, _, "", "", _))
      .WillOnce(Return(connection_));

  EXPECT_CALL(*connection_, FinishRequestAsync(_, _))
      .WillOnce(DoAll(WithArg<0>(Invoke(finish_request_async)), Return(23)));

  EXPECT_EQ(23, request.GetResponse(success_callback, {}));
}

}  // namespace http
}  // namespace brillo
