// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/socket/tcp_client_socket.h"

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/io_buffer.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_log.h"
#include "net/base/net_log_unittest.h"
#include "net/base/net_errors.h"
#include "net/base/tcp_listen_socket.h"
#include "net/base/test_completion_callback.h"
#include "net/base/winsock_init.h"
#include "net/socket/client_socket_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace net {

namespace {

const char kServerReply[] = "HTTP/1.1 404 Not Found";

enum ClientSocketTestTypes {
  TCP,
  SCTP
};

}  // namespace

class TransportClientSocketTest
    : public StreamListenSocket::Delegate,
      public ::testing::TestWithParam<ClientSocketTestTypes> {
 public:
  TransportClientSocketTest()
      : listen_port_(0),
        socket_factory_(ClientSocketFactory::GetDefaultFactory()),
        close_server_socket_on_next_send_(false) {
  }

  ~TransportClientSocketTest() {
  }

  // Implement StreamListenSocket::Delegate methods
  virtual void DidAccept(StreamListenSocket* server,
                         StreamListenSocket* connection) {
    connected_sock_ = reinterpret_cast<TCPListenSocket*>(connection);
  }
  virtual void DidRead(StreamListenSocket*, const char* str, int len) {
    // TODO(dkegel): this might not be long enough to tickle some bugs.
    connected_sock_->Send(kServerReply, arraysize(kServerReply) - 1,
                          false /* Don't append line feed */);
    if (close_server_socket_on_next_send_)
      CloseServerSocket();
  }
  virtual void DidClose(StreamListenSocket* sock) {}

  // Testcase hooks
  virtual void SetUp();

  void CloseServerSocket() {
    // delete the connected_sock_, which will close it.
    connected_sock_ = NULL;
  }

  void PauseServerReads() {
    connected_sock_->PauseReads();
  }

  void ResumeServerReads() {
    connected_sock_->ResumeReads();
  }

  int DrainClientSocket(IOBuffer* buf,
                        uint32 buf_len,
                        uint32 bytes_to_read,
                        TestCompletionCallback* callback);

  void SendClientRequest();

  void set_close_server_socket_on_next_send(bool close) {
    close_server_socket_on_next_send_ = close;
  }

 protected:
  int listen_port_;
  CapturingNetLog net_log_;
  ClientSocketFactory* const socket_factory_;
  scoped_ptr<StreamSocket> sock_;

 private:
  scoped_refptr<TCPListenSocket> listen_sock_;
  scoped_refptr<TCPListenSocket> connected_sock_;
  bool close_server_socket_on_next_send_;
};

void TransportClientSocketTest::SetUp() {
  ::testing::TestWithParam<ClientSocketTestTypes>::SetUp();

  // Find a free port to listen on
  scoped_refptr<TCPListenSocket> sock;
  int port;
#if defined(STARBOARD)
  // Let the system choose a port for us.
  sock = TCPListenSocket::CreateAndListen("127.0.0.1", 0, this);
  ASSERT_TRUE(sock != NULL);
  IPEndPoint address;
  ASSERT_TRUE(sock->GetLocalAddress(&address) == 0);
  port = address.port();
#else
  // Range of ports to listen on.  Shouldn't need to try many.
  const int kMinPort = 10100;
  const int kMaxPort = 10200;
#if defined(OS_WIN)
  EnsureWinsockInit();
#endif
  for (port = kMinPort; port < kMaxPort; port++) {
    sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this);
    if (sock.get())
      break;
  }
#endif
  ASSERT_TRUE(sock != NULL);
  listen_sock_ = sock;
  listen_port_ = port;

  AddressList addr;
  // MockHostResolver resolves everything to 127.0.0.1.
  scoped_ptr<HostResolver> resolver(new MockHostResolver());
  HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
  TestCompletionCallback callback;
  int rv = resolver->Resolve(info, &addr, callback.callback(), NULL,
                             BoundNetLog());
  CHECK_EQ(ERR_IO_PENDING, rv);
  rv = callback.WaitForResult();
  CHECK_EQ(rv, OK);
  sock_.reset(
      socket_factory_->CreateTransportClientSocket(addr,
                                                   &net_log_,
                                                   NetLog::Source()));
}

int TransportClientSocketTest::DrainClientSocket(
    IOBuffer* buf, uint32 buf_len,
    uint32 bytes_to_read, TestCompletionCallback* callback) {
  int rv = OK;
  uint32 bytes_read = 0;

  while (bytes_read < bytes_to_read) {
    rv = sock_->Read(buf, buf_len, callback->callback());
    EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);

    if (rv == ERR_IO_PENDING)
      rv = callback->WaitForResult();

    EXPECT_GE(rv, 0);
    bytes_read += rv;
  }

  return static_cast<int>(bytes_read);
}

void TransportClientSocketTest::SendClientRequest() {
  const char request_text[] = "GET / HTTP/1.0\r\n\r\n";
  scoped_refptr<IOBuffer> request_buffer(
      new IOBuffer(arraysize(request_text) - 1));
  TestCompletionCallback callback;
  int rv;

  memcpy(request_buffer->data(), request_text, arraysize(request_text) - 1);
  rv = sock_->Write(request_buffer, arraysize(request_text) - 1,
                    callback.callback());
  EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);

  if (rv == ERR_IO_PENDING)
    rv = callback.WaitForResult();
  EXPECT_EQ(rv, static_cast<int>(arraysize(request_text) - 1));
}

// TODO(leighton):  Add SCTP to this list when it is ready.
INSTANTIATE_TEST_CASE_P(StreamSocket,
                        TransportClientSocketTest,
                        ::testing::Values(TCP));

TEST_P(TransportClientSocketTest, Connect) {
  TestCompletionCallback callback;
  EXPECT_FALSE(sock_->IsConnected());

  int rv = sock_->Connect(callback.callback());

  net::CapturingNetLog::CapturedEntryList net_log_entries;
  net_log_.GetEntries(&net_log_entries);
  EXPECT_TRUE(net::LogContainsBeginEvent(
      net_log_entries, 0, net::NetLog::TYPE_SOCKET_ALIVE));
  EXPECT_TRUE(net::LogContainsBeginEvent(
      net_log_entries, 1, net::NetLog::TYPE_TCP_CONNECT));
  if (rv != OK) {
    ASSERT_EQ(rv, ERR_IO_PENDING);
    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }

  EXPECT_TRUE(sock_->IsConnected());
  net_log_.GetEntries(&net_log_entries);
  EXPECT_TRUE(net::LogContainsEndEvent(
      net_log_entries, -1, net::NetLog::TYPE_TCP_CONNECT));

  sock_->Disconnect();
  EXPECT_FALSE(sock_->IsConnected());
}

TEST_P(TransportClientSocketTest, IsConnected) {
  scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
  TestCompletionCallback callback;
  uint32 bytes_read;

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_FALSE(sock_->IsConnectedAndIdle());
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(rv, ERR_IO_PENDING);
    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_TRUE(sock_->IsConnectedAndIdle());

  // Send the request and wait for the server to respond.
  SendClientRequest();

  // Drain a single byte so we know we've received some data.
  bytes_read = DrainClientSocket(buf, 1, 1, &callback);
  ASSERT_EQ(bytes_read, 1u);

  // Socket should be considered connected, but not idle, due to
  // pending data.
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_FALSE(sock_->IsConnectedAndIdle());

  bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2,
                                 &callback);
  ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);

  // After draining the data, the socket should be back to connected
  // and idle.
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_TRUE(sock_->IsConnectedAndIdle());

  // This time close the server socket immediately after the server response.
  set_close_server_socket_on_next_send(true);
  SendClientRequest();

  bytes_read = DrainClientSocket(buf, 1, 1, &callback);
  ASSERT_EQ(bytes_read, 1u);

  // As above because of data.
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_FALSE(sock_->IsConnectedAndIdle());

  bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 2,
                                 &callback);
  ASSERT_EQ(bytes_read, arraysize(kServerReply) - 2);

  // Once the data is drained, the socket should now be seen as not
  // connected.
  if (sock_->IsConnected()) {
    // In the unlikely event that the server's connection closure is not
    // processed in time, wait for the connection to be closed.
    rv = sock_->Read(buf, 4096, callback.callback());
    EXPECT_EQ(0, callback.GetResult(rv));
    EXPECT_FALSE(sock_->IsConnected());
  }
  EXPECT_FALSE(sock_->IsConnectedAndIdle());
}

TEST_P(TransportClientSocketTest, Read) {
  TestCompletionCallback callback;
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(rv, ERR_IO_PENDING);

    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }
  SendClientRequest();

  scoped_refptr<IOBuffer> buf(new IOBuffer(4096));
  uint32 bytes_read = DrainClientSocket(buf, 4096, arraysize(kServerReply) - 1,
                                        &callback);
  ASSERT_EQ(bytes_read, arraysize(kServerReply) - 1);

  // All data has been read now.  Read once more to force an ERR_IO_PENDING, and
  // then close the server socket, and note the close.

  rv = sock_->Read(buf, 4096, callback.callback());
  ASSERT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(static_cast<int64>(std::string(kServerReply).size()),
            sock_->NumBytesRead());
  CloseServerSocket();
  EXPECT_EQ(0, callback.WaitForResult());
}

TEST_P(TransportClientSocketTest, Read_SmallChunks) {
  TestCompletionCallback callback;
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(rv, ERR_IO_PENDING);

    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }
  SendClientRequest();

  scoped_refptr<IOBuffer> buf(new IOBuffer(1));
  uint32 bytes_read = 0;
  while (bytes_read < arraysize(kServerReply) - 1) {
    rv = sock_->Read(buf, 1, callback.callback());
    EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);

    if (rv == ERR_IO_PENDING)
      rv = callback.WaitForResult();

    ASSERT_EQ(1, rv);
    bytes_read += rv;
  }

  // All data has been read now.  Read once more to force an ERR_IO_PENDING, and
  // then close the server socket, and note the close.

  rv = sock_->Read(buf, 1, callback.callback());
  EXPECT_EQ(static_cast<int64>(std::string(kServerReply).size()),
            sock_->NumBytesRead());
  ASSERT_EQ(ERR_IO_PENDING, rv);
  CloseServerSocket();
  EXPECT_EQ(0, callback.WaitForResult());
}

TEST_P(TransportClientSocketTest, Read_Interrupted) {
  TestCompletionCallback callback;
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(ERR_IO_PENDING, rv);

    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }
  SendClientRequest();

  // Do a partial read and then exit.  This test should not crash!
  scoped_refptr<IOBuffer> buf(new IOBuffer(16));
  rv = sock_->Read(buf, 16, callback.callback());
  EXPECT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
  EXPECT_EQ(0, sock_->NumBytesRead());

  if (rv == ERR_IO_PENDING) {
    rv = callback.WaitForResult();
    EXPECT_EQ(16, sock_->NumBytesRead());
  }

  EXPECT_NE(0, rv);
}

TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_ReadFirst) {
  TestCompletionCallback callback;
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(rv, ERR_IO_PENDING);

    rv = callback.WaitForResult();
    EXPECT_EQ(rv, OK);
  }

  // Read first.  There's no data, so it should return ERR_IO_PENDING.
  const int kBufLen = 4096;
  scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
  rv = sock_->Read(buf, kBufLen, callback.callback());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  PauseServerReads();
  const int kWriteBufLen = 64 * 1024;
  scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
  char* request_data = request_buffer->data();
  memset(request_data, 'A', kWriteBufLen);
  TestCompletionCallback write_callback;

  while (true) {
    rv = sock_->Write(request_buffer, kWriteBufLen, write_callback.callback());
    ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);

    if (rv == ERR_IO_PENDING) {
      ResumeServerReads();
      rv = write_callback.WaitForResult();
      break;
    }
  }

  // At this point, both read and write have returned ERR_IO_PENDING, and the
  // write callback has executed.  We wait for the read callback to run now to
  // make sure that the socket can handle full duplex communications.

  rv = callback.WaitForResult();
  EXPECT_GE(rv, 0);
}

TEST_P(TransportClientSocketTest, DISABLED_FullDuplex_WriteFirst) {
  TestCompletionCallback callback;
  int rv = sock_->Connect(callback.callback());
  if (rv != OK) {
    ASSERT_EQ(ERR_IO_PENDING, rv);

    rv = callback.WaitForResult();
    EXPECT_EQ(OK, rv);
  }

  PauseServerReads();
  const int kWriteBufLen = 64 * 1024;
  scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kWriteBufLen));
  char* request_data = request_buffer->data();
  memset(request_data, 'A', kWriteBufLen);
  TestCompletionCallback write_callback;

  while (true) {
    rv = sock_->Write(request_buffer, kWriteBufLen, write_callback.callback());
    ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);

    if (rv == ERR_IO_PENDING)
      break;
  }

  // Now we have the Write() blocked on ERR_IO_PENDING.  It's time to force the
  // Read() to block on ERR_IO_PENDING too.

  const int kBufLen = 4096;
  scoped_refptr<IOBuffer> buf(new IOBuffer(kBufLen));
  while (true) {
    rv = sock_->Read(buf, kBufLen, callback.callback());
    ASSERT_TRUE(rv >= 0 || rv == ERR_IO_PENDING);
    if (rv == ERR_IO_PENDING)
      break;
  }

  // At this point, both read and write have returned ERR_IO_PENDING.  Now we
  // run the write and read callbacks to make sure they can handle full duplex
  // communications.

  ResumeServerReads();
  rv = write_callback.WaitForResult();
  EXPECT_GE(rv, 0);

  // It's possible the read is blocked because it's already read all the data.
  // Close the server socket, so there will at least be a 0-byte read.
  CloseServerSocket();

  rv = callback.WaitForResult();
  EXPECT_GE(rv, 0);
}

}  // namespace net
