/*
 *  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";

const char* const kHttpResponsePrefix =
    "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"
    "8\r\n"
    "Goodbye!\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), obtain_stream(false), 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);
    if (obtain_stream) {
      ObtainDocumentStream();
    }
    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 ObtainDocumentStream();
  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;

  // Document stream, and stream events
  bool obtain_stream;
  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::ObtainDocumentStream() {
  RTC_LOG_F(LS_VERBOSE) << "Enter";
  EXPECT_FALSE(http_stream);
  http_stream = base.GetDocumentStream();
  ASSERT_TRUE(nullptr != http_stream);
  sink.Monitor(http_stream);
  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!");
}

TEST_F(HttpBaseTest, SupportsReceiveViaStreamPull) {
  // Switch to pull mode
  ObtainDocumentStream();
  VerifyDocumentStreamIsOpening();

  // Queue response document
  SetupSource(kHttpResponse);
  VerifyDocumentStreamIsOpening();

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

  // Pull document data
  VerifyDocumentStreamOpenEvent();
  ReadDocumentStreamData("Goodbye!");
  VerifyDocumentStreamIsEOS();

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

TEST_F(HttpBaseTest, DISABLED_AllowsCloseStreamBeforeDocumentIsComplete) {
  // TODO: Remove extra logging once test failure is understood
  LoggingSeverity old_sev = rtc::LogMessage::GetLogToDebug();
  rtc::LogMessage::LogToDebug(LS_VERBOSE);

  // Switch to pull mode
  ObtainDocumentStream();
  VerifyDocumentStreamIsOpening();

  // Queue response document
  SetupSource(kHttpResponse);
  VerifyDocumentStreamIsOpening();

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

  // Pull some of the data
  VerifyDocumentStreamOpenEvent();
  ReadDocumentStreamData("Goodb");

  // We've seen the header by now
  VerifyHeaderComplete(1, false);

  // Close the pull stream, this will transition back to push I/O.
  http_stream->Close();
  Thread::Current()->ProcessMessages(0);

  // Remainder of document completed successfully
  VerifyTransferComplete(HM_RECV, HE_NONE);
  VerifyDocumentContents("ye!");

  rtc::LogMessage::LogToDebug(old_sev);
}

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

  // Switch to pull mode in response to header arrival
  obtain_stream = true;

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

  // We've already seen the header, but not data has arrived
  VerifyHeaderComplete(1, false);
  VerifyDocumentContents("");

  // Pull the document data
  ReadDocumentStreamData("Goodbye!");
  VerifyDocumentStreamIsEOS();

  // Document completed successfully
  VerifyTransferComplete(HM_RECV, HE_NONE);
  VerifyDocumentContents("");
}

TEST_F(HttpBaseTest, AllowsGetDocumentStreamWithEmptyDocumentBody) {
  // Queue empty response document
  SetupSource(kHttpEmptyResponse);

  // Switch to pull mode in response to header arrival
  obtain_stream = true;

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

  // We've already seen the header, but not data has arrived
  VerifyHeaderComplete(1, true);
  VerifyDocumentContents("");

  // The document is still open, until we attempt to read
  ASSERT_TRUE(nullptr != http_stream);
  EXPECT_EQ(SS_OPEN, http_stream->GetState());

  // Attempt to read data, and discover EOS
  VerifyDocumentStreamIsEOS();

  // Document completed successfully
  VerifyTransferComplete(HM_RECV, HE_NONE);
  VerifyDocumentContents("");
}

TEST_F(HttpBaseTest, SignalsDocumentStreamCloseOnUnexpectedClose) {
  // Switch to pull mode
  ObtainDocumentStream();
  VerifyDocumentStreamIsOpening();

  // Queue response document
  SetupSource(kHttpResponsePrefix);
  VerifyDocumentStreamIsOpening();

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

  // Pull document data
  VerifyDocumentStreamOpenEvent();
  ReadDocumentStreamData("Goodbye!");

  // Simulate unexpected close
  src.SetState(SS_CLOSED);

  // Observe error event on document stream
  EXPECT_EQ(webrtc::testing::SSE_ERROR, sink.Events(http_stream));

  // Future reads give an error
  int error = 0;
  char buffer[5] = {0};
  EXPECT_EQ(SR_ERROR,
            http_stream->Read(buffer, sizeof(buffer), nullptr, &error));
  EXPECT_EQ(HE_DISCONNECTED, error);

  // Document completed with error
  VerifyHeaderComplete(2, false);
  VerifyTransferComplete(HM_RECV, HE_DISCONNECTED);
  VerifyDocumentContents("");
}

}  // namespace rtc
