// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <utility>

#include "starboard/common/log.h"
#include "starboard/common/socket.h"
#include "starboard/nplb/socket_helpers.h"
#include "starboard/nplb/thread_helpers.h"
#include "starboard/socket_waiter.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

class SbSocketWaiterWaitTest
    : public ::testing::TestWithParam<SbSocketAddressType> {
 public:
  SbSocketAddressType GetAddressType() { return GetParam(); }
};

class PairSbSocketWaiterWaitTest
    : public ::testing::TestWithParam<
          std::pair<SbSocketAddressType, SbSocketAddressType> > {
 public:
  SbSocketAddressType GetServerAddressType() { return GetParam().first; }
  SbSocketAddressType GetClientAddressType() { return GetParam().second; }
};

struct CallbackValues {
  int count;
  SbSocketWaiter waiter;
  SbSocket socket;
  void* context;
  int ready_interests;
};

void TestSocketWaiterCallback(SbSocketWaiter waiter,
                              SbSocket socket,
                              void* context,
                              int ready_interests) {
  CallbackValues* values = reinterpret_cast<CallbackValues*>(context);
  if (values) {
    ++values->count;
    values->waiter = waiter;
    values->socket = socket;
    values->context = context;
    values->ready_interests = ready_interests;
  }
  SbSocketWaiterWakeUp(waiter);
}

void FailSocketWaiterCallback(SbSocketWaiter waiter,
                              SbSocket socket,
                              void* context,
                              int ready_interests) {
  ADD_FAILURE() << __FUNCTION__ << " was called.";
}

TEST_P(PairSbSocketWaiterWaitTest, SunnyDay) {
  const int kBufSize = 1024;

  SbSocketWaiter waiter = SbSocketWaiterCreate();
  EXPECT_TRUE(SbSocketWaiterIsValid(waiter));

  ConnectedTrio trio =
      CreateAndConnect(GetServerAddressType(), GetClientAddressType(),
                       GetPortNumberForTests(), kSocketTimeout);
  ASSERT_TRUE(SbSocketIsValid(trio.server_socket));

  // The client socket should be ready to write right away, but not read until
  // it gets some data.
  CallbackValues values = {0};
  EXPECT_TRUE(SbSocketWaiterAdd(
      waiter, trio.client_socket, &values, &TestSocketWaiterCallback,
      kSbSocketWaiterInterestRead | kSbSocketWaiterInterestWrite, false));

  // This add should do nothing, since it is already registered. Testing here
  // because we can see if it fires a write to the proper callback, then it
  // properly ignored this second set of parameters.
  EXPECT_FALSE(SbSocketWaiterAdd(waiter, trio.client_socket, &values,
                                 &FailSocketWaiterCallback,
                                 kSbSocketWaiterInterestRead, false));

  WaitShouldNotBlock(waiter);

  EXPECT_EQ(1, values.count);  // Check that the callback was called once.
  EXPECT_EQ(waiter, values.waiter);
  EXPECT_EQ(trio.client_socket, values.socket);
  EXPECT_EQ(&values, values.context);
  EXPECT_EQ(kSbSocketWaiterInterestWrite, values.ready_interests);

  // Try again to make sure writable sockets are still writable
  values.count = 0;
  EXPECT_TRUE(SbSocketWaiterAdd(
      waiter, trio.client_socket, &values, &TestSocketWaiterCallback,
      kSbSocketWaiterInterestRead | kSbSocketWaiterInterestWrite, false));

  WaitShouldNotBlock(waiter);

  EXPECT_EQ(1, values.count);  // Check that the callback was called once.
  EXPECT_EQ(waiter, values.waiter);
  EXPECT_EQ(trio.client_socket, values.socket);
  EXPECT_EQ(&values, values.context);
  EXPECT_EQ(kSbSocketWaiterInterestWrite, values.ready_interests);

  // The client socket should become ready to read after we write some data to
  // it.
  values.count = 0;
  EXPECT_TRUE(SbSocketWaiterAdd(waiter, trio.client_socket, &values,
                                &TestSocketWaiterCallback,
                                kSbSocketWaiterInterestRead, false));

  // Now we can send something to trigger readability.
  char* send_buf = new char[kBufSize];
  int bytes_sent = SbSocketSendTo(trio.server_socket, send_buf, kBufSize, NULL);
  delete[] send_buf;
  EXPECT_LT(0, bytes_sent);

  WaitShouldNotBlock(waiter);

  EXPECT_EQ(1, values.count);
  EXPECT_EQ(waiter, values.waiter);
  EXPECT_EQ(trio.client_socket, values.socket);
  EXPECT_EQ(&values, values.context);
  EXPECT_EQ(kSbSocketWaiterInterestRead, values.ready_interests);

  EXPECT_TRUE(SbSocketDestroy(trio.server_socket));
  EXPECT_TRUE(SbSocketDestroy(trio.client_socket));
  EXPECT_TRUE(SbSocketDestroy(trio.listen_socket));
  EXPECT_TRUE(SbSocketWaiterDestroy(waiter));
}

struct AlreadyReadyContext {
  AlreadyReadyContext()
      : waiter(kSbSocketWaiterInvalid),
        a_write_result(false),
        a_read_result(false),
        b_result(false) {}
  ~AlreadyReadyContext() {
    if (SbSocketIsValid(trio.listen_socket)) {
      EXPECT_TRUE(SbSocketDestroy(trio.listen_socket));
    }
    if (SbSocketIsValid(trio.server_socket)) {
      EXPECT_TRUE(SbSocketDestroy(trio.server_socket));
    }
    if (SbSocketIsValid(trio.client_socket)) {
      EXPECT_TRUE(SbSocketDestroy(trio.client_socket));
    }
    EXPECT_TRUE(SbSocketWaiterDestroy(waiter));
  }

  SbSocketWaiter waiter;
  ConnectedTrio trio;
  Semaphore wrote_a_signal;
  bool a_write_result;
  bool a_read_result;
  Semaphore write_b_signal;
  bool b_result;
  Semaphore wrote_b_signal;
};

const char kAData[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
const char kBData[] = "bb";

void* AlreadyReadyEntryPoint(void* param) {
  AlreadyReadyContext* context = reinterpret_cast<AlreadyReadyContext*>(param);

  context->a_write_result =
      WriteBySpinning(context->trio.server_socket, kAData,
                      SB_ARRAY_SIZE_INT(kAData), kSocketTimeout);
  context->wrote_a_signal.Put();

  context->write_b_signal.Take();
  context->b_result =
      WriteBySpinning(context->trio.server_socket, kBData,
                      SB_ARRAY_SIZE_INT(kBData), kSocketTimeout);
  context->wrote_b_signal.Put();
  return NULL;
}

void WakeUpSocketWaiterCallback(SbSocketWaiter waiter,
                                SbSocket socket,
                                void* param,
                                int ready_interests) {
  SbSocketWaiterWakeUp(waiter);
}

void AlreadyReadySocketWaiterCallback(SbSocketWaiter waiter,
                                      SbSocket socket,
                                      void* param,
                                      int ready_interests) {
  AlreadyReadyContext* context = reinterpret_cast<AlreadyReadyContext*>(param);
  // Read in the A data.
  char buffer[SB_ARRAY_SIZE_INT(kAData)];
  context->a_read_result =
      ReadBySpinning(context->trio.client_socket, buffer,
                     SB_ARRAY_SIZE_INT(buffer), kSocketTimeout);

  // Tell the thread to write the B data now.
  context->write_b_signal.Put();

  // Wait until it thinks it has finished.
  context->wrote_b_signal.Take();

  // Now add the second read callback, and hope that it gets called.
  EXPECT_TRUE(SbSocketWaiterAdd(waiter, socket, context,
                                &WakeUpSocketWaiterCallback,
                                kSbSocketWaiterInterestRead, false));
}

// This test ensures that if the socket gets written to while it is not being
// waited on, and inside a callback, it will become ready immediately the next
// time it is waited on.
TEST_P(PairSbSocketWaiterWaitTest, SunnyDayAlreadyReady) {
  AlreadyReadyContext context;
  context.waiter = SbSocketWaiterCreate();
  ASSERT_TRUE(SbSocketWaiterIsValid(context.waiter));

  context.trio =
      CreateAndConnect(GetServerAddressType(), GetClientAddressType(),
                       GetPortNumberForTests(), kSocketTimeout);
  ASSERT_TRUE(SbSocketIsValid(context.trio.server_socket));

  EXPECT_TRUE(SbSocketWaiterAdd(context.waiter, context.trio.client_socket,
                                &context, &AlreadyReadySocketWaiterCallback,
                                kSbSocketWaiterInterestRead, false));

  SbThread thread =
      SbThreadCreate(0, kSbThreadNoPriority, kSbThreadNoAffinity, true, NULL,
                     AlreadyReadyEntryPoint, &context);
  EXPECT_TRUE(SbThreadIsValid(thread));
  context.wrote_a_signal.Take();

  WaitShouldNotBlock(context.waiter);

  EXPECT_TRUE(SbThreadJoin(thread, NULL));
}

TEST_F(SbSocketWaiterWaitTest, RainyDayInvalidWaiter) {
  WaitShouldNotBlock(kSbSocketWaiterInvalid);
}

#if SB_HAS(IPV6)
INSTANTIATE_TEST_CASE_P(SbSocketAddressTypes,
                        SbSocketWaiterWaitTest,
                        ::testing::Values(kSbSocketAddressTypeIpv4,
                                          kSbSocketAddressTypeIpv6));
INSTANTIATE_TEST_CASE_P(
    SbSocketAddressTypes,
    PairSbSocketWaiterWaitTest,
    ::testing::Values(
        std::make_pair(kSbSocketAddressTypeIpv4, kSbSocketAddressTypeIpv4),
        std::make_pair(kSbSocketAddressTypeIpv6, kSbSocketAddressTypeIpv6),
        std::make_pair(kSbSocketAddressTypeIpv6, kSbSocketAddressTypeIpv4)));
#else
INSTANTIATE_TEST_CASE_P(SbSocketAddressTypes,
                        SbSocketWaiterWaitTest,
                        ::testing::Values(kSbSocketAddressTypeIpv4));
INSTANTIATE_TEST_CASE_P(
    SbSocketAddressTypes,
    PairSbSocketWaiterWaitTest,
    ::testing::Values(std::make_pair(kSbSocketAddressTypeIpv4,
                                     kSbSocketAddressTypeIpv4)));
#endif

}  // namespace
}  // namespace nplb
}  // namespace starboard
