/*
 *  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 {
    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 {
    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 {
    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) {
  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);
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyHeaderComplete(size_t event_count, bool empty_doc) {
  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);
  }
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentContents(const char* expected_data,
                                          size_t expected_length) {
  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));
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::ObtainDocumentStream() {
  LOG_F(LS_VERBOSE) << "Enter";
  EXPECT_FALSE(http_stream);
  http_stream = base.GetDocumentStream();
  ASSERT_TRUE(nullptr != http_stream);
  sink.Monitor(http_stream);
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamIsOpening() {
  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));
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamOpenEvent() {
  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);
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::ReadDocumentStreamData(const char* expected_data) {
  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;
  }
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamIsEOS() {
  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));
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::SetupDocument(const char* document_data) {
  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");
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifySourceContents(const char* expected_data,
                                        size_t expected_length) {
  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));
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyTransferComplete(HttpMode mode, HttpError error) {
  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);
  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
