// 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_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)

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