// Copyright 2015 Google Inc. 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/log.h"
#include "starboard/nplb/socket_helpers.h"
#include "starboard/socket.h"
#include "starboard/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

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

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

bool IsNonIdleWithin(SbSocket socket, SbTimeMonotonic timeout) {
  SbTimeMonotonic deadline = SbTimeGetMonotonicNow() + timeout;
  while (SbTimeGetMonotonicNow() < deadline) {
    if (!SbSocketIsConnectedAndIdle(socket)) {
      return true;
    }
  }
  return false;
}

TEST_F(SbSocketIsConnectedAndIdleTest, RainyDayInvalidSocket) {
  EXPECT_FALSE(SbSocketIsConnectedAndIdle(kSbSocketInvalid));
}

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

  EXPECT_FALSE(SbSocketIsConnectedAndIdle(trio.listen_socket));
  EXPECT_TRUE(SbSocketIsConnectedAndIdle(trio.server_socket));
  EXPECT_TRUE(SbSocketIsConnectedAndIdle(trio.client_socket));

  char buf[512] = {0};
  SbSocketSendTo(trio.server_socket, buf, sizeof(buf), NULL);
  // It may take some time after this call for trio.client_socket to show up as
  // having new data available, even though it is a loopback connection, so we
  // give it a grace period.
  EXPECT_TRUE(IsNonIdleWithin(trio.client_socket, kSocketTimeout));

  // Should be the same in the other direction.
  SbSocketSendTo(trio.client_socket, buf, sizeof(buf), NULL);
  EXPECT_TRUE(IsNonIdleWithin(trio.server_socket, kSocketTimeout));

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

TEST_P(SbSocketIsConnectedAndIdleTest, SunnyDayNotConnected) {
  SbSocket socket = SbSocketCreate(GetAddressType(), kSbSocketProtocolTcp);
  ASSERT_TRUE(SbSocketIsValid(socket));
  EXPECT_TRUE(IsNonIdleWithin(socket, kSocketTimeout));
  EXPECT_TRUE(SbSocketDestroy(socket));
}

TEST_P(SbSocketIsConnectedAndIdleTest, SunnyDayListeningNotConnected) {
  SbSocket server_socket =
      CreateListeningTcpSocket(GetAddressType(), GetPortNumberForTests());
  ASSERT_TRUE(SbSocketIsValid(server_socket));
  EXPECT_FALSE(SbSocketIsConnectedAndIdle(server_socket));
  EXPECT_TRUE(SbSocketDestroy(server_socket));
}

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

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