// Copyright 2017 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 "starboard/nplb/socket_helpers.h"
#include "starboard/socket.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const unsigned char kInvalidByte = 0xFE;

}  // namespace

namespace starboard {
namespace nplb {
namespace {

#if SB_API_VERSION >= 4
class SbSocketGetInterfaceAddressTest
    : public ::testing::TestWithParam<SbSocketAddressType> {
 public:
  SbSocketAddressType GetAddressType() { return GetParam(); }
};

TEST(SbSocketGetInterfaceAddressTest, SunnyDay) {
  SbSocketAddress invalid_address;
  SbSocketAddress address;

  // Initialize to something invalid.
  SbMemorySet(&address, kInvalidByte, sizeof(address));
  SbMemorySet(&invalid_address, kInvalidByte, sizeof(invalid_address));

  EXPECT_TRUE(SbSocketGetInterfaceAddress(NULL, &address, NULL));
  EXPECT_EQ(0, address.port);
  EXPECT_FALSE(IsUnspecified(&address));
  EXPECT_FALSE(IsLocalhost(&address));
  EXPECT_NE(0, SbMemoryCompare(address.address, invalid_address.address,
                               SB_ARRAY_SIZE(address.address)));
}

TEST(SbSocketGetInterfaceAddressTest, RainyDayNull) {
  EXPECT_FALSE(SbSocketGetInterfaceAddress(NULL, NULL, NULL));
}

TEST(SbSocketGetInterfaceAddressTest, SunnyDayNullDestination) {
  SbSocketAddress netmask;
  SbSocketAddress source;

  SbMemorySet(&netmask, kInvalidByte, sizeof(netmask));
  SbMemorySet(&source, kInvalidByte, sizeof(source));

  // If destination address is NULL, then any IP address that is valid for
  // |destination| set to 0.0.0.0 (IPv4) or :: (IPv6) can be returned.

  EXPECT_TRUE(SbSocketGetInterfaceAddress(NULL, &source, NULL));
  EXPECT_TRUE(source.type == kSbSocketAddressTypeIpv4 ||
              source.type == kSbSocketAddressTypeIpv6);

  EXPECT_TRUE(SbSocketGetInterfaceAddress(NULL, &source, &netmask));
  // A netmask that starts with 0 is likely incorrect.
  EXPECT_TRUE(netmask.address[0] & 0x8);
  EXPECT_TRUE(source.type == kSbSocketAddressTypeIpv4 ||
              source.type == kSbSocketAddressTypeIpv6);
  EXPECT_TRUE(netmask.type == kSbSocketAddressTypeIpv4 ||
              netmask.type == kSbSocketAddressTypeIpv6);
}

TEST_P(SbSocketGetInterfaceAddressTest, SunnyDayDestination) {
  SbSocketAddress destination = {0};
  destination.type = GetAddressType();

  SbSocketAddress netmask;
  SbSocketAddress source;

  // Initialize to something invalid.
  SbMemorySet(&netmask, kInvalidByte, sizeof(netmask));
  SbMemorySet(&source, kInvalidByte, sizeof(source));

  EXPECT_TRUE(SbSocketGetInterfaceAddress(&destination, &source, NULL));
  EXPECT_TRUE(source.type == GetAddressType());
  EXPECT_TRUE(SbSocketGetInterfaceAddress(&destination, &source, &netmask));

  EXPECT_FALSE(IsLocalhost(&source));

  // A netmask that starts with 0 is likely incorrect.
  EXPECT_TRUE(netmask.address[0] & 0x8);
  EXPECT_EQ(source.type, GetAddressType());
  EXPECT_EQ(netmask.type, GetAddressType());
  EXPECT_EQ(source.port, 0);
}

TEST_P(SbSocketGetInterfaceAddressTest, SunnyDaySourceForDestination) {
  const char kTestHostName[] = "www.example.com";

  SbSocketResolveFilter resolve_filter = kSbSocketResolveFilterNone;
  switch (GetAddressType()) {
    case kSbSocketAddressTypeIpv4:
      resolve_filter = kSbSocketResolveFilterIpv4;
      break;
    case kSbSocketAddressTypeIpv6:
      resolve_filter = kSbSocketResolveFilterIpv6;
      break;
    default:
      FAIL() << "Invalid address type " << GetAddressType();
  }
  SbSocketResolution* resolution =
      SbSocketResolve(kTestHostName, resolve_filter);

  // TODO: Switch to nullptr, when C++11 is available.
  ASSERT_NE(resolution, reinterpret_cast<SbSocketResolution*>(NULL));
  ASSERT_NE(resolution->address_count, 0);
  SbSocketAddress& destination_address = resolution->addresses[0];

  SbSocketAddress source;
  SbSocketAddress netmask;
  SbSocketAddress invalid_address;
  SbMemorySet(&netmask, kInvalidByte, sizeof(netmask));
  SbMemorySet(&source, kInvalidByte, sizeof(source));
  SbMemorySet(&invalid_address, kInvalidByte, sizeof(source));
  SbSocketGetInterfaceAddress(&destination_address, &source, &netmask);

  EXPECT_TRUE(source.type == GetAddressType());
  EXPECT_NE(source.port, 0);
  // A netmask that starts with 0 is likely incorrect.
  EXPECT_TRUE(netmask.address[0] & 0x8);
  EXPECT_EQ(netmask.type, GetAddressType());
  EXPECT_NE(0, SbMemoryCompare(source.address, invalid_address.address,
                               SB_ARRAY_SIZE(source.address)));
  EXPECT_NE(0, SbMemoryCompare(netmask.address, invalid_address.address,
                               SB_ARRAY_SIZE(netmask.address)));

  SbSocketFreeResolution(resolution);
}

TEST_P(SbSocketGetInterfaceAddressTest, SunnyDaySourceNotLoopback) {
  SbSocketAddress destination = {0};
  destination.type = GetAddressType();

  // If the destination address is 0.0.0.0, and its |type| is
  // |kSbSocketAddressTypeIpv4|, then any IPv4 local interface that is up and
  // not a loopback interface is a valid return value.
  //
  // If the destination address is ::, and its |type| is
  // |kSbSocketAddressTypeIpv6| then any IPv6 local interface that is up and
  // not loopback or a link-local IP is a valid return value.  However, in the
  // case of IPv6, the address with the biggest scope must be returned.  E.g., a
  // globally scoped and routable IP is prefered over a unique local address
  // (ULA). Also, the IP address that is returned must be permanent.

  SbSocketAddress netmask;
  SbSocketAddress source;
  SbSocketAddress invalid_address;

  // Initialize to something invalid.
  SbMemorySet(&netmask, kInvalidByte, sizeof(netmask));
  SbMemorySet(&source, kInvalidByte, sizeof(source));
  SbMemorySet(&invalid_address, kInvalidByte, sizeof(invalid_address));

  EXPECT_TRUE(SbSocketGetInterfaceAddress(&destination, &source, NULL));
  EXPECT_EQ(source.type, GetAddressType());
  EXPECT_TRUE(SbSocketGetInterfaceAddress(&destination, &source, &netmask));
  EXPECT_FALSE(IsLocalhost(&source));
  EXPECT_FALSE(IsUnspecified(&source));

  EXPECT_NE(0, SbMemoryCompare(netmask.address, invalid_address.address,
                               SB_ARRAY_SIZE(netmask.address)));
  EXPECT_NE(0, SbMemoryCompare(source.address, invalid_address.address,
                               SB_ARRAY_SIZE(source.address)));
}

#if SB_HAS(IPV6)
INSTANTIATE_TEST_CASE_P(SbSocketAddressTypes,
                        SbSocketGetInterfaceAddressTest,
                        ::testing::Values(kSbSocketAddressTypeIpv4,
                                          kSbSocketAddressTypeIpv6));
#else
INSTANTIATE_TEST_CASE_P(SbSocketAddressTypes,
                        SbSocketGetInterfaceAddressTest,
                        ::testing::Values(kSbSocketAddressTypeIpv4));
#endif  // SB_HAS(IPV6)

#endif  // SB_API_VERSION >= 4

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