// 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 "ppapi/tests/test_tcp_socket_private.h"

#include <stddef.h>
#include <stdlib.h>

#include <new>

#include "ppapi/cpp/private/tcp_socket_private.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

namespace {

// Validates the first line of an HTTP response.
bool ValidateHttpResponse(const std::string& s) {
  // Just check that it begins with "HTTP/" and ends with a "\r\n".
  return s.size() >= 5 &&
         s.substr(0, 5) == "HTTP/" &&
         s.substr(s.size() - 2) == "\r\n";
}

}  // namespace

REGISTER_TEST_CASE(TCPSocketPrivate);

TestTCPSocketPrivate::TestTCPSocketPrivate(TestingInstance* instance)
    : TestCase(instance) {
}

bool TestTCPSocketPrivate::Init() {
  if (!pp::TCPSocketPrivate::IsAvailable())
    return false;

  // We need something to connect to, so we connect to the HTTP server whence we
  // came. Grab the host and port.
  if (!EnsureRunningOverHTTP())
    return false;

  if (!GetLocalHostPort(instance_->pp_instance(), &host_, &port_))
    return false;

  // Get the port for the SSL server.
  ssl_port_ = instance_->ssl_server_port();

  return true;
}

void TestTCPSocketPrivate::RunTests(const std::string& filter) {
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, Basic, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWrite, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, ReadWriteSSL, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, ConnectAddress, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, SetOption, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, LargeRead, filter);

  RUN_CALLBACK_TEST(TestTCPSocketPrivate, SSLHandshakeFails, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, SSLHandshakeHangs, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, SSLWriteFails, filter);
  RUN_CALLBACK_TEST(TestTCPSocketPrivate, SSLReadFails, filter);
}

std::string TestTCPSocketPrivate::TestBasic() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  PP_NetAddress_Private unused;
  // TODO(viettrungluu): check the values somehow.
  ASSERT_TRUE(socket.GetLocalAddress(&unused));
  ASSERT_TRUE(socket.GetRemoteAddress(&unused));

  socket.Disconnect();

  PASS();
}

std::string TestTCPSocketPrivate::TestReadWrite() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));

  // Read up to the first \n and check that it looks like valid HTTP response.
  std::string s;
  ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
  ASSERT_TRUE(ValidateHttpResponse(s));

  socket.Disconnect();

  PASS();
}

std::string TestTCPSocketPrivate::TestReadWriteSSL() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect(host_.c_str(), ssl_port_, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(
      socket.SSLHandshake(host_.c_str(), ssl_port_, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));

  // Read up to the first \n and check that it looks like valid HTTP response.
  std::string s;
  ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
  ASSERT_TRUE(ValidateHttpResponse(s));

  socket.Disconnect();

  PASS();
}

std::string TestTCPSocketPrivate::TestConnectAddress() {
  PP_NetAddress_Private address;

  // First, bring up a connection and grab the address.
  {
    pp::TCPSocketPrivate socket(instance_);
    TestCompletionCallback cb(instance_->pp_instance(), callback_type());
    cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(cb);
    ASSERT_EQ(PP_OK, cb.result());
    ASSERT_TRUE(socket.GetRemoteAddress(&address));
    // Omit the |Disconnect()| here to make sure we don't crash if we just let
    // the resource be destroyed.
  }

  // Connect to that address.
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());
  cb.WaitForResult(socket.ConnectWithNetAddress(&address, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  // Make sure we can read/write to it properly (see |TestReadWrite()|).
  ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));
  std::string s;
  ASSERT_EQ(PP_OK, ReadFirstLineFromSocket(&socket, &s));
  ASSERT_TRUE(ValidateHttpResponse(s));

  socket.Disconnect();

  PASS();
}

std::string TestTCPSocketPrivate::TestSetOption() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(
      socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
                       cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_FAILED, cb.result());

  cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(
      socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_NO_DELAY, true,
                       cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(
      socket.SetOption(PP_TCPSOCKETOPTION_PRIVATE_INVALID, true,
                       cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_BADARGUMENT, cb.result());

  socket.Disconnect();

  PASS();
}

std::string TestTCPSocketPrivate::TestLargeRead() {
  pp::TCPSocketPrivate socket(instance_);
  {
    TestCompletionCallback cb(instance_->pp_instance(), callback_type());

    cb.WaitForResult(socket.Connect(host_.c_str(), port_, cb.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(cb);
    ASSERT_EQ(PP_OK, cb.result());
  }

  ASSERT_EQ(PP_OK, WriteStringToSocket(&socket, "GET / HTTP/1.0\r\n\r\n"));

  const size_t kReadSize = 1024 * 1024 + 32;
  // Create large buffer in heap to prevent run-time errors related to
  // limits on stack size.
  char* buffer = new (std::nothrow) char[kReadSize];
  ASSERT_TRUE(buffer != NULL);

  TestCompletionCallback cb(instance_->pp_instance(), callback_type());
  cb.WaitForResult(socket.Read(buffer, kReadSize * sizeof(*buffer),
                               cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_LE(0, cb.result());

  delete [] buffer;

  PASS();
}

std::string TestTCPSocketPrivate::TestSSLHandshakeFails() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(socket.SSLHandshake("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_FAILED, cb.result());

  // Writes and reads should both fail after an SSL handshake fails.

  char byte = 'a';
  cb.WaitForResult(socket.Write(&byte, 1, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_FAILED, cb.result());

  cb.WaitForResult(socket.Read(&byte, 1, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_FAILED, cb.result());

  PASS();
}

std::string TestTCPSocketPrivate::TestSSLHandshakeHangs() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  socket.SSLHandshake("foo.test", 443, DoNothingCallback());
  PASS();
}

std::string TestTCPSocketPrivate::TestSSLWriteFails() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(socket.SSLHandshake("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  // Write to the socket until there's an error. Some writes may succeed, since
  // Mojo writes complete before the socket tries to send data.
  char write_data[32 * 1024] = {0};
  while (true) {
    TestCompletionCallback cb(instance_->pp_instance(), callback_type());
    cb.WaitForResult(socket.Write(write_data,
                                  static_cast<int32_t>(sizeof(write_data)),
                                  cb.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(cb);
    if (cb.result() > 0)
      continue;

    ASSERT_EQ(PP_ERROR_FAILED, cb.result());
    PASS();
  }
}

std::string TestTCPSocketPrivate::TestSSLReadFails() {
  pp::TCPSocketPrivate socket(instance_);
  TestCompletionCallback cb(instance_->pp_instance(), callback_type());

  cb.WaitForResult(socket.Connect("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  cb.WaitForResult(socket.SSLHandshake("foo.test", 443, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_OK, cb.result());

  char byte;
  cb.WaitForResult(socket.Read(&byte, 1, cb.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(cb);
  ASSERT_EQ(PP_ERROR_FAILED, cb.result());

  PASS();
}

int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket(
    pp::TCPSocketPrivate* socket,
    std::string* s) {
  char buffer[10000];

  s->clear();
  // Make sure we don't just hang if |Read()| spews.
  while (s->size() < 1000000) {
    TestCompletionCallback cb(instance_->pp_instance(), callback_type());
    int32_t rv = socket->Read(buffer, sizeof(buffer), cb.GetCallback());
    if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
      return PP_ERROR_FAILED;
    cb.WaitForResult(rv);
    if (cb.result() < 0)
      return cb.result();
    if (cb.result() == 0)
      return PP_ERROR_FAILED;  // Didn't get a \n-terminated line.
    s->reserve(s->size() + cb.result());
    for (int32_t i = 0; i < cb.result(); i++) {
      s->push_back(buffer[i]);
      if (buffer[i] == '\n')
        return PP_OK;
    }
  }
  return PP_ERROR_FAILED;
}

int32_t TestTCPSocketPrivate::WriteStringToSocket(pp::TCPSocketPrivate* socket,
                                                  const std::string& s) {
  const char* buffer = s.data();
  size_t written = 0;
  while (written < s.size()) {
    TestCompletionCallback cb(instance_->pp_instance(), callback_type());
    int32_t rv = socket->Write(buffer + written,
                               static_cast<int32_t>(s.size() - written),
                               cb.GetCallback());
    if (callback_type() == PP_REQUIRED && rv != PP_OK_COMPLETIONPENDING)
      return PP_ERROR_FAILED;
    cb.WaitForResult(rv);
    if (cb.result() < 0)
      return cb.result();
    if (cb.result() == 0)
      return PP_ERROR_FAILED;
    written += cb.result();
  }
  if (written != s.size())
    return PP_ERROR_FAILED;
  return PP_OK;
}
