/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <algorithm>

#include "rtc_base/gunit.h"
#include "rtc_base/httpbase.h"
#include "rtc_base/testutils.h"

namespace rtc {

const char* const kHttpResponse =
    "HTTP/1.1 200\r\n"
    "Connection: Keep-Alive\r\n"
    "Content-Type: text/plain\r\n"
    "Proxy-Authorization: 42\r\n"
    "Transfer-Encoding: chunked\r\n"
    "\r\n"
    "00000008\r\n"
    "Goodbye!\r\n"
    "0\r\n\r\n";

const char* const kHttpEmptyResponse =
    "HTTP/1.1 200\r\n"
    "Connection: Keep-Alive\r\n"
    "Content-Length: 0\r\n"
    "Proxy-Authorization: 42\r\n"
    "\r\n";

class HttpBaseTest : public testing::Test, public IHttpNotify {
 public:
  enum EventType { E_HEADER_COMPLETE, E_COMPLETE, E_CLOSED };
  struct Event {
    EventType event;
    bool chunked;
    size_t data_size;
    HttpMode mode;
    HttpError err;
  };
  HttpBaseTest() : mem(nullptr), http_stream(nullptr) {}

  void TearDown() override {
    delete http_stream;
    // Avoid an ASSERT, in case a test doesn't clean up properly
    base.abort(HE_NONE);
  }

  HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) override {
    RTC_LOG_F(LS_VERBOSE) << "chunked: " << chunked << " size: " << data_size;
    Event e = {E_HEADER_COMPLETE, chunked, data_size, HM_NONE, HE_NONE};
    events.push_back(e);
    return HE_NONE;
  }
  void onHttpComplete(HttpMode mode, HttpError err) override {
    RTC_LOG_F(LS_VERBOSE) << "mode: " << mode << " err: " << err;
    Event e = {E_COMPLETE, false, 0, mode, err};
    events.push_back(e);
  }
  void onHttpClosed(HttpError err) override {
    RTC_LOG_F(LS_VERBOSE) << "err: " << err;
    Event e = {E_CLOSED, false, 0, HM_NONE, err};
    events.push_back(e);
  }

  void SetupSource(const char* response);

  void VerifyHeaderComplete(size_t event_count, bool empty_doc);
  void VerifyDocumentContents(const char* expected_data,
                              size_t expected_length = SIZE_UNKNOWN);

  void VerifyDocumentStreamIsOpening();
  void VerifyDocumentStreamOpenEvent();
  void ReadDocumentStreamData(const char* expected_data);
  void VerifyDocumentStreamIsEOS();

  void SetupDocument(const char* response);
  void VerifySourceContents(const char* expected_data,
                            size_t expected_length = SIZE_UNKNOWN);

  void VerifyTransferComplete(HttpMode mode, HttpError error);

  HttpBase base;
  MemoryStream* mem;
  HttpResponseData data;

  // The source of http data, and source events
  webrtc::testing::StreamSource src;
  std::vector<Event> events;

  // Stream events
  StreamInterface* http_stream;
  webrtc::testing::StreamSink sink;
};

void HttpBaseTest::SetupSource(const char* http_data) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  src.SetState(SS_OPENING);
  src.QueueString(http_data);

  base.notify(this);
  base.attach(&src);
  EXPECT_TRUE(events.empty());

  src.SetState(SS_OPEN);
  ASSERT_EQ(1U, events.size());
  EXPECT_EQ(E_COMPLETE, events[0].event);
  EXPECT_EQ(HM_CONNECT, events[0].mode);
  EXPECT_EQ(HE_NONE, events[0].err);
  events.clear();

  mem = new MemoryStream;
  data.document.reset(mem);
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyHeaderComplete(size_t event_count, bool empty_doc) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  ASSERT_EQ(event_count, events.size());
  EXPECT_EQ(E_HEADER_COMPLETE, events[0].event);

  std::string header;
  EXPECT_EQ(HVER_1_1, data.version);
  EXPECT_EQ(static_cast<uint32_t>(HC_OK), data.scode);
  EXPECT_TRUE(data.hasHeader(HH_PROXY_AUTHORIZATION, &header));
  EXPECT_EQ("42", header);
  EXPECT_TRUE(data.hasHeader(HH_CONNECTION, &header));
  EXPECT_EQ("Keep-Alive", header);

  if (empty_doc) {
    EXPECT_FALSE(events[0].chunked);
    EXPECT_EQ(0U, events[0].data_size);

    EXPECT_TRUE(data.hasHeader(HH_CONTENT_LENGTH, &header));
    EXPECT_EQ("0", header);
  } else {
    EXPECT_TRUE(events[0].chunked);
    EXPECT_EQ(SIZE_UNKNOWN, events[0].data_size);

    EXPECT_TRUE(data.hasHeader(HH_CONTENT_TYPE, &header));
    EXPECT_EQ("text/plain", header);
    EXPECT_TRUE(data.hasHeader(HH_TRANSFER_ENCODING, &header));
    EXPECT_EQ("chunked", header);
  }
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentContents(const char* expected_data,
                                          size_t expected_length) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  if (SIZE_UNKNOWN == expected_length) {
    expected_length = strlen(expected_data);
  }
  EXPECT_EQ(mem, data.document.get());

  size_t length;
  mem->GetSize(&length);
  EXPECT_EQ(expected_length, length);
  EXPECT_TRUE(0 == memcmp(expected_data, mem->GetBuffer(), length));
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamIsOpening() {
  RTC_LOG_F(LS_VERBOSE) << "Enter";
  ASSERT_TRUE(nullptr != http_stream);
  EXPECT_EQ(0, sink.Events(http_stream));
  EXPECT_EQ(SS_OPENING, http_stream->GetState());

  size_t read = 0;
  char buffer[5] = {0};
  EXPECT_EQ(SR_BLOCK,
            http_stream->Read(buffer, sizeof(buffer), &read, nullptr));
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamOpenEvent() {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  ASSERT_TRUE(nullptr != http_stream);
  EXPECT_EQ(SE_OPEN | SE_READ, sink.Events(http_stream));
  EXPECT_EQ(SS_OPEN, http_stream->GetState());

  // HTTP headers haven't arrived yet
  EXPECT_EQ(0U, events.size());
  EXPECT_EQ(static_cast<uint32_t>(HC_INTERNAL_SERVER_ERROR), data.scode);
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::ReadDocumentStreamData(const char* expected_data) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  ASSERT_TRUE(nullptr != http_stream);
  EXPECT_EQ(SS_OPEN, http_stream->GetState());

  // Pump the HTTP I/O using Read, and verify the results.
  size_t verified_length = 0;
  const size_t expected_length = strlen(expected_data);
  while (verified_length < expected_length) {
    size_t read = 0;
    char buffer[5] = {0};
    size_t amt_to_read =
        std::min(expected_length - verified_length, sizeof(buffer));
    EXPECT_EQ(SR_SUCCESS,
              http_stream->Read(buffer, amt_to_read, &read, nullptr));
    EXPECT_EQ(amt_to_read, read);
    EXPECT_TRUE(0 == memcmp(expected_data + verified_length, buffer, read));
    verified_length += read;
  }
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamIsEOS() {
  RTC_LOG_F(LS_VERBOSE) << "Enter";

  ASSERT_TRUE(nullptr != http_stream);
  size_t read = 0;
  char buffer[5] = {0};
  EXPECT_EQ(SR_EOS, http_stream->Read(buffer, sizeof(buffer), &read, nullptr));
  EXPECT_EQ(SS_CLOSED, http_stream->GetState());

  // When EOS is caused by Read, we don't expect SE_CLOSE
  EXPECT_EQ(0, sink.Events(http_stream));
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::SetupDocument(const char* document_data) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";
  src.SetState(SS_OPEN);

  base.notify(this);
  base.attach(&src);
  EXPECT_TRUE(events.empty());

  if (document_data) {
    // Note: we could just call data.set_success("text/plain", mem), but that
    // won't allow us to use the chunked transfer encoding.
    mem = new MemoryStream(document_data);
    data.document.reset(mem);
    data.setHeader(HH_CONTENT_TYPE, "text/plain");
    data.setHeader(HH_TRANSFER_ENCODING, "chunked");
  } else {
    data.setHeader(HH_CONTENT_LENGTH, "0");
  }
  data.scode = HC_OK;
  data.setHeader(HH_PROXY_AUTHORIZATION, "42");
  data.setHeader(HH_CONNECTION, "Keep-Alive");
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifySourceContents(const char* expected_data,
                                        size_t expected_length) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";
  if (SIZE_UNKNOWN == expected_length) {
    expected_length = strlen(expected_data);
  }
  std::string contents = src.ReadData();
  EXPECT_EQ(expected_length, contents.length());
  EXPECT_TRUE(0 == memcmp(expected_data, contents.data(), expected_length));
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyTransferComplete(HttpMode mode, HttpError error) {
  RTC_LOG_F(LS_VERBOSE) << "Enter";
  // Verify that http operation has completed
  ASSERT_TRUE(events.size() > 0);
  size_t last_event = events.size() - 1;
  EXPECT_EQ(E_COMPLETE, events[last_event].event);
  EXPECT_EQ(mode, events[last_event].mode);
  EXPECT_EQ(error, events[last_event].err);
  RTC_LOG_F(LS_VERBOSE) << "Exit";
}

//
// Tests
//

TEST_F(HttpBaseTest, SupportsSend) {
  // Queue response document
  SetupDocument("Goodbye!");

  // Begin send
  base.send(&data);

  // Send completed successfully
  VerifyTransferComplete(HM_SEND, HE_NONE);
  VerifySourceContents(kHttpResponse);
}

TEST_F(HttpBaseTest, SupportsSendNoDocument) {
  // Queue response document
  SetupDocument(nullptr);

  // Begin send
  base.send(&data);

  // Send completed successfully
  VerifyTransferComplete(HM_SEND, HE_NONE);
  VerifySourceContents(kHttpEmptyResponse);
}

TEST_F(HttpBaseTest, SignalsCompleteOnInterruptedSend) {
  // This test is attempting to expose a bug that occurs when a particular
  // base objects is used for receiving, and then used for sending.  In
  // particular, the HttpParser state is different after receiving.  Simulate
  // that here.
  SetupSource(kHttpResponse);
  base.recv(&data);
  VerifyTransferComplete(HM_RECV, HE_NONE);

  src.Clear();
  data.clear(true);
  events.clear();
  base.detach();

  // Queue response document
  SetupDocument("Goodbye!");

  // Prevent entire response from being sent
  const size_t kInterruptedLength = strlen(kHttpResponse) - 1;
  src.SetWriteBlock(kInterruptedLength);

  // Begin send
  base.send(&data);

  // Document is mostly complete, but no completion signal yet.
  EXPECT_TRUE(events.empty());
  VerifySourceContents(kHttpResponse, kInterruptedLength);

  src.SetState(SS_CLOSED);

  // Send completed with disconnect error, and no additional data.
  VerifyTransferComplete(HM_SEND, HE_DISCONNECTED);
  EXPECT_TRUE(src.ReadData().empty());
}

TEST_F(HttpBaseTest, SupportsReceiveViaDocumentPush) {
  // Queue response document
  SetupSource(kHttpResponse);

  // Begin receive
  base.recv(&data);

  // Document completed successfully
  VerifyHeaderComplete(2, false);
  VerifyTransferComplete(HM_RECV, HE_NONE);
  VerifyDocumentContents("Goodbye!");
}

}  // namespace rtc
