// Copyright 2015 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 "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

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

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

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

SbSocket CreateSendSocket() {
  SbSocket socket = CreateUdpIpv4Socket();
  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 = GetIpv4Unspecified(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;
      }

      FAIL() << "Failed to send multicast packet: " << error;
      return;
    }
    EXPECT_EQ(SB_ARRAY_SIZE_INT(kBuf), sent);
    break;
  }

  SbSocketAddress receive_address;
  while (true) {
    int received = SbSocketReceiveFrom(
        receive_socket, buf, SB_ARRAY_SIZE_INT(buf), &receive_address);
    if (received < 0 &&
        SbSocketGetLastError(receive_socket) == kSbSocketPending) {
      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 = GetIpv4Unspecified(0);
  EXPECT_FALSE(SbSocketJoinMulticastGroup(kSbSocketInvalid, &address));
}

TEST(SbSocketJoinMulticastGroupTest, RainyDayInvalidAddress) {
  SbSocket socket = CreateUdpIpv4Socket();
  EXPECT_TRUE(SbSocketIsValid(socket));
  EXPECT_FALSE(SbSocketJoinMulticastGroup(socket, NULL));
  EXPECT_TRUE(SbSocketDestroy(socket));
}

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