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

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

namespace starboard {
namespace nplb {
namespace {

SbSocket CreateMulticastSocket(const SbSocketAddress& address) {
  SbSocket socket =
      SbSocketCreate(kSbSocketAddressTypeIpv4, kSbSocketProtocolUdp);
  EXPECT_TRUE(SbSocketIsValid(socket));
  EXPECT_TRUE(SbSocketSetReuseAddress(socket, true));

  // It will choose a port for me.
  SbSocketAddress bind_address =
      GetUnspecifiedAddress(kSbSocketAddressTypeIpv4, 0);
  EXPECT_EQ(kSbSocketOk, SbSocketBind(socket, &bind_address));

  EXPECT_TRUE(SbSocketJoinMulticastGroup(socket, &address));
  return socket;
}

SbSocket CreateSendSocket() {
  SbSocket socket =
      SbSocketCreate(kSbSocketAddressTypeIpv4, kSbSocketProtocolUdp);
  EXPECT_TRUE(SbSocketIsValid(socket));
  EXPECT_TRUE(SbSocketSetReuseAddress(socket, true));
  return socket;
}

TEST(SbSocketJoinMulticastGroupTest, SunnyDay) {
  // "224.0.2.0" is an unassigned ad-hoc multicast address. Hopefully no one is
  // spamming it on the local network.
  // http://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
  SbSocketAddress address = GetUnspecifiedAddress(kSbSocketAddressTypeIpv4, 0);
  address.address[0] = 224;
  address.address[2] = 2;

  SbSocket send_socket = CreateSendSocket();
  SbSocket receive_socket = CreateMulticastSocket(address);

  // Get the bound port.
  SbSocketAddress local_address = {0};
  SbSocketGetLocalAddress(receive_socket, &local_address);
  address.port = local_address.port;

  const char kBuf[] = "01234567890123456789";
  char buf[SB_ARRAY_SIZE(kBuf)] = {0};
  while (true) {
    int sent =
        SbSocketSendTo(send_socket, kBuf, SB_ARRAY_SIZE_INT(kBuf), &address);
    if (sent < 0) {
      SbSocketError error = SbSocketGetLastError(send_socket);
      if (error == kSbSocketPending) {
        continue;
      }

      // Clean up the sockets.
      EXPECT_TRUE(SbSocketDestroy(send_socket));
      EXPECT_TRUE(SbSocketDestroy(receive_socket));
      FAIL() << "Failed to send multicast packet: " << error;
      return;
    }
    EXPECT_EQ(SB_ARRAY_SIZE_INT(kBuf), sent);
    break;
  }

  SbSocketAddress receive_address;
  SbTimeMonotonic stop_time = SbTimeGetMonotonicNow() + kSbTimeSecond;
  while (true) {
    // Breaks the case where the test will hang in a loop when
    // SbSocketReceiveFrom() always returns kSbSocketPending.
    ASSERT_LE(SbTimeGetMonotonicNow(), stop_time) << "Multicast timed out.";
    int received = SbSocketReceiveFrom(
        receive_socket, buf, SB_ARRAY_SIZE_INT(buf), &receive_address);
    if (received < 0 &&
        SbSocketGetLastError(receive_socket) == kSbSocketPending) {
      SbThreadSleep(kSbTimeMillisecond);
      continue;
    }
    EXPECT_EQ(SB_ARRAY_SIZE_INT(kBuf), received);
    break;
  }

  for (int i = 0; i < SB_ARRAY_SIZE_INT(kBuf); ++i) {
    EXPECT_EQ(kBuf[i], buf[i]) << "position " << i;
  }

  EXPECT_TRUE(SbSocketDestroy(send_socket));
  EXPECT_TRUE(SbSocketDestroy(receive_socket));
}

TEST(SbSocketJoinMulticastGroupTest, RainyDayInvalidSocket) {
  SbSocketAddress address = GetUnspecifiedAddress(kSbSocketAddressTypeIpv4, 0);
  EXPECT_FALSE(SbSocketJoinMulticastGroup(kSbSocketInvalid, &address));
}

TEST(SbSocketJoinMulticastGroupTest, RainyDayInvalidAddress) {
  SbSocket socket =
      SbSocketCreate(kSbSocketAddressTypeIpv4, kSbSocketProtocolUdp);
  ASSERT_TRUE(SbSocketIsValid(socket));
  EXPECT_FALSE(SbSocketJoinMulticastGroup(socket, NULL));
  EXPECT_TRUE(SbSocketDestroy(socket));
}

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