/*
 * libjingle
 * Copyright 2004--2011, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/base/gunit.h"
#include "talk/base/httpbase.h"
#include "talk/base/testutils.h"

namespace talk_base {

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(NULL), obtain_stream(false), http_stream(NULL) { }

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

  virtual HttpError onHttpHeaderComplete(bool chunked, size_t& data_size) {
    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;
  }
  virtual void onHttpComplete(HttpMode mode, HttpError err) {
    LOG_F(LS_VERBOSE) << "mode: " << mode << " err: " << err;
    Event e = { E_COMPLETE, false, 0, mode, err };
    events.push_back(e);
  }
  virtual void onHttpClosed(HttpError err) {
    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
  testing::StreamSource src;
  std::vector<Event> events;

  // Document stream, and stream events
  bool obtain_stream;
  StreamInterface* http_stream;
  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>(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(NULL != http_stream);
  sink.Monitor(http_stream);
  LOG_F(LS_VERBOSE) << "Exit";
}

void HttpBaseTest::VerifyDocumentStreamIsOpening() {
  LOG_F(LS_VERBOSE) << "Enter";
  ASSERT_TRUE(NULL != 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, NULL));
  LOG_F(LS_VERBOSE) << "Exit";
}

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

  ASSERT_TRUE(NULL != 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>(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(NULL != 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 = _min(expected_length - verified_length, sizeof(buffer));
    EXPECT_EQ(SR_SUCCESS, http_stream->Read(buffer, amt_to_read, &read, NULL));
    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(NULL != http_stream);
  size_t read = 0;
  char buffer[5] = { 0 };
  EXPECT_EQ(SR_EOS, http_stream->Read(buffer, sizeof(buffer), &read, NULL));
  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(NULL);

  // 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
  int old_sev = talk_base::LogMessage::GetLogToDebug();
  talk_base::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!");

  talk_base::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(NULL != 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(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), NULL, &error));
  EXPECT_EQ(HE_DISCONNECTED, error);

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

} // namespace talk_base
