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

namespace starboard {
namespace nplb {
namespace {

const unsigned char kInvalidByte = 0xFE;

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_EQ(GetAddressType(), source.type);
  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(GetAddressType(), source.type);
  EXPECT_EQ(GetAddressType(), netmask.type);
  EXPECT_EQ(0, source.port);
}

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_EQ(GetAddressType(), source.type);
  EXPECT_NE(0, source.port);
  // A netmask that starts with 0 is likely incorrect.
  EXPECT_TRUE(netmask.address[0] & 0x8);
  EXPECT_EQ(GetAddressType(), netmask.type);
  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(GetAddressType(), source.type);
  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)

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