// 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.

// The basic Sunny Day test is a subset of other Sunny Day tests, so it is not
// repeated here.

#include <utility>

#include "starboard/common/socket.h"
#include "starboard/nplb/socket_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

class SbSocketBindTest
    : public ::testing::TestWithParam<
          std::pair<SbSocketAddressType, SbSocketResolveFilter> > {
 public:
  SbSocketAddressType GetAddressType() { return GetParam().first; }
  SbSocketResolveFilter GetFilterType() { return GetParam().second; }
};

#if SB_HAS(IPV6)
class PairSbSocketBindTest
    : public ::testing::TestWithParam<
          std::pair<SbSocketAddressType, SbSocketAddressType> > {
 public:
  SbSocketAddressType GetServerAddressType() { return GetParam().first; }
  SbSocketAddressType GetClientAddressType() { return GetParam().second; }
};
#endif

// This is to use NULL in asserts, which otherwise complain about long
// vs. pointer type.
const void* kNull = NULL;

TEST_P(SbSocketBindTest, RainyDayNullSocket) {
  SbSocketAddress address =
      GetUnspecifiedAddress(GetAddressType(), GetPortNumberForTests());
  EXPECT_SB_SOCKET_ERROR_IS_ERROR(SbSocketBind(kSbSocketInvalid, &address));
}

TEST_P(SbSocketBindTest, RainyDayNullAddress) {
  SbSocket server_socket = CreateServerTcpSocket(GetAddressType());
  ASSERT_TRUE(SbSocketIsValid(server_socket));

  // Binding with a NULL address should fail.
  EXPECT_SB_SOCKET_ERROR_IS_ERROR(SbSocketBind(server_socket, NULL));

  // Even though that failed, binding the same socket now with 0.0.0.0:2048
  // should work.
  SbSocketAddress address =
      GetUnspecifiedAddress(GetAddressType(), GetPortNumberForTests());
  EXPECT_EQ(kSbSocketOk, SbSocketBind(server_socket, &address));

  EXPECT_TRUE(SbSocketDestroy(server_socket));
}

TEST_F(SbSocketBindTest, RainyDayNullNull) {
  EXPECT_SB_SOCKET_ERROR_IS_ERROR(SbSocketBind(kSbSocketInvalid, NULL));
}

#if SB_HAS(IPV6)
TEST_P(PairSbSocketBindTest, RainyDayWrongAddressType) {
  SbSocket server_socket = CreateServerTcpSocket(GetServerAddressType());
  ASSERT_TRUE(SbSocketIsValid(server_socket));

  // Binding with the wrong address type should fail.
  SbSocketAddress address =
      GetUnspecifiedAddress(GetClientAddressType(), GetPortNumberForTests());
  EXPECT_SB_SOCKET_ERROR_IS_ERROR(SbSocketBind(server_socket, &address));

  // Even though that failed, binding the same socket now with the server
  // address type should work.
  address =
      GetUnspecifiedAddress(GetServerAddressType(), GetPortNumberForTests());
  EXPECT_EQ(kSbSocketOk, SbSocketBind(server_socket, &address));

  EXPECT_TRUE(SbSocketDestroy(server_socket));
}
#endif

TEST_P(SbSocketBindTest, RainyDayBadInterface) {
  SbSocket server_socket = CreateServerTcpSocket(GetAddressType());
  ASSERT_TRUE(SbSocketIsValid(server_socket));

  // Binding with an interface that doesn't exist on this device should fail, so
  // let's find an address of a well-known public website that we shouldn't be
  // able to bind to.
  const char* kTestHostName = "www.yahoo.com";
  SbSocketResolution* resolution =
      SbSocketResolve(kTestHostName, GetFilterType());
  ASSERT_NE(kNull, resolution);
  EXPECT_LT(0, resolution->address_count);
  EXPECT_SB_SOCKET_ERROR_IS_ERROR(
      SbSocketBind(server_socket, &resolution->addresses[0]));

  EXPECT_TRUE(SbSocketDestroy(server_socket));
  SbSocketFreeResolution(resolution);
}

TEST_F(SbSocketBindTest, SunnyDayLocalInterface) {
  SbSocketAddress address = {0};
  EXPECT_TRUE(SbSocketGetInterfaceAddress(NULL, &address, NULL));
  SbSocket server_socket = CreateServerTcpSocket(address.type);
  ASSERT_TRUE(SbSocketIsValid(server_socket));

  EXPECT_EQ(kSbSocketOk, SbSocketBind(server_socket, &address));

  EXPECT_TRUE(SbSocketDestroy(server_socket));
}

#if SB_HAS(IPV6)
INSTANTIATE_TEST_CASE_P(
    SbSocketAddressTypes,
    SbSocketBindTest,
    ::testing::Values(
        std::make_pair(kSbSocketAddressTypeIpv4, kSbSocketResolveFilterIpv4),
        std::make_pair(kSbSocketAddressTypeIpv6, kSbSocketResolveFilterIpv6)));
INSTANTIATE_TEST_CASE_P(
    SbSocketAddressTypes,
    PairSbSocketBindTest,
    ::testing::Values(
        std::make_pair(kSbSocketAddressTypeIpv4, kSbSocketAddressTypeIpv6),
        std::make_pair(kSbSocketAddressTypeIpv6, kSbSocketAddressTypeIpv4)));
#else
INSTANTIATE_TEST_CASE_P(
    SbSocketAddressTypes,
    SbSocketBindTest,
    ::testing::Values(std::make_pair(kSbSocketAddressTypeIpv4,
                                     kSbSocketResolveFilterIpv4)));
#endif

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