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