// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cast/streaming/packet_util.h"

#include "absl/types/span.h"
#include "gtest/gtest.h"

namespace openscreen {
namespace cast {
namespace {

// Tests that a simple RTCP packet containing only a Sender Report can be
// identified.
TEST(PacketUtilTest, InspectsRtcpPacketFromSender) {
  // clang-format off
  const uint8_t kSenderReportPacket[] = {
    0b10000000,  // Version=2, Padding=no, ItemCount=0.
    200,  // RTCP Packet type.
    0x00, 0x06,  // Length of remainder of packet, in 32-bit words.
    1, 2, 3, 4,  // SSRC of sender.
    0xe0, 0x73, 0x2e, 0x54,  // NTP Timestamp (late evening on 2019-04-30).
        0x80, 0x00, 0x00, 0x00,
    0x00, 0x14, 0x99, 0x70,  // RTP Timestamp (15 seconds, 90kHz timebase).
    0x00, 0x00, 0x01, 0xff,  // Sender's Packet Count.
    0x00, 0x07, 0x11, 0x0d,  // Sender's Octet Count.
  };
  // clang-format on
  const Ssrc kSenderSsrc = 0x01020304;

  const auto result = InspectPacketForRouting(kSenderReportPacket);
  EXPECT_EQ(ApparentPacketType::RTCP, result.first);
  EXPECT_EQ(kSenderSsrc, result.second);
}

// Tests that compound RTCP packets containing a Receiver Report and/or a Cast
// Feedback message can be identified.
TEST(PacketUtilTest, InspectsRtcpPacketFromReceiver) {
  // clang-format off
  const uint8_t kReceiverReportPacket[] = {
    0b10000001,  // Version=2, Padding=no, ItemCount=1.
    201,  // RTCP Packet type.
    0x00, 0x01,  // Length of remainder of packet, in 32-bit words.
    9, 8, 7, 6,  // SSRC of receiver.
  };
  const uint8_t kCastFeedbackPacket[] = {
    // Cast Feedback
    0b10000000 | 15,  // Version=2, Padding=no, Subtype=15.
    206,  // RTCP Packet type byte.
    0x00, 0x04,  // Length of remainder of packet, in 32-bit words.
    9, 8, 7, 6,  // SSRC of receiver.
    1, 2, 3, 4,  // SSRC of sender.
    'C', 'A', 'S', 'T',
    0x0a,  // Checkpoint Frame ID (lower 8 bits).
    0x00,  // Number of "Loss Fields"
    0x00, 0x28,  // Current Playout Delay in milliseconds.
  };
  // clang-format on
  const Ssrc kReceiverSsrc = 0x09080706;

  {
    const auto result = InspectPacketForRouting(kReceiverReportPacket);
    EXPECT_EQ(ApparentPacketType::RTCP, result.first);
    EXPECT_EQ(kReceiverSsrc, result.second);
  }

  {
    const auto result = InspectPacketForRouting(kCastFeedbackPacket);
    EXPECT_EQ(ApparentPacketType::RTCP, result.first);
    EXPECT_EQ(kReceiverSsrc, result.second);
  }

  const absl::Span<const uint8_t> kCompoundCombinations[2][2] = {
      {kReceiverReportPacket, kCastFeedbackPacket},
      {kCastFeedbackPacket, kReceiverReportPacket},
  };
  for (const auto& combo : kCompoundCombinations) {
    uint8_t compound_packet[sizeof(kReceiverReportPacket) +
                            sizeof(kCastFeedbackPacket)];
    memcpy(compound_packet, combo[0].data(), combo[0].size());
    memcpy(compound_packet + combo[0].size(), combo[1].data(), combo[1].size());

    const auto result = InspectPacketForRouting(compound_packet);
    EXPECT_EQ(ApparentPacketType::RTCP, result.first);
    EXPECT_EQ(kReceiverSsrc, result.second);
  }
}

// Tests that a RTP packet can be identified.
TEST(PacketUtilTest, InspectsRtpPacket) {
  // clang-format off
  const uint8_t kInput[] = {
    0b10000000,  // Version/Padding byte.
    96,  // Payload type byte.
    0xbe, 0xef,  // Sequence number.
    9, 8, 7, 6,  // RTP timestamp.
    1, 2, 3, 4,  // SSRC.
    0b10000000,  // Is key frame, no extensions.
    5,  // Frame ID.
    0xa, 0xb,  // Packet ID.
    0xa, 0xc,  // Max packet ID.
    0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
  };
  // clang-format on
  const Ssrc kSenderSsrc = 0x01020304;

  const auto result = InspectPacketForRouting(kInput);
  EXPECT_EQ(ApparentPacketType::RTP, result.first);
  EXPECT_EQ(kSenderSsrc, result.second);
}

// Tests that a RTP packet with the "127 payload type" hack can be identified as
// valid. See comments in rtp_defines.h for the RtpPayloadType enum definition,
// for further details.
TEST(PacketUtilTest, InspectsAndroidAudioRtpPacket) {
  // clang-format off
  const uint8_t kInput[] = {
    0b10000000,  // Version/Padding byte.
    127,  // Payload type byte.
    0xbe, 0xef,  // Sequence number.
    9, 8, 7, 6,  // RTP timestamp.
    1, 2, 3, 4,  // SSRC.
    0b10000000,  // Is key frame, no extensions.
    5,  // Frame ID.
    0xa, 0xb,  // Packet ID.
    0xa, 0xc,  // Max packet ID.
    0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
  };
  // clang-format on
  const Ssrc kSenderSsrc = 0x01020304;

  const auto result = InspectPacketForRouting(kInput);
  EXPECT_EQ(ApparentPacketType::RTP, result.first);
  EXPECT_EQ(kSenderSsrc, result.second);
}

// Tests that a malformed RTP packet can be identified.
TEST(PacketUtilTest, InspectsMalformedRtpPacket) {
  // clang-format off
  const uint8_t kInput[] = {
    0b11000000,  // BAD: Version/Padding byte.
    96,  // Payload type byte.
    0xbe, 0xef,  // Sequence number.
    9, 8, 7, 6,  // RTP timestamp.
    1, 2, 3, 4,  // SSRC.
    0b10000000,  // Is key frame, no extensions.
    5,  // Frame ID.
    0xa, 0xb,  // Packet ID.
    0xa, 0xc,  // Max packet ID.
    0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
  };
  // clang-format on

  const auto result = InspectPacketForRouting(kInput);
  EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
}

// Tests that an empty packet is classified as unknown.
TEST(PacketUtilTest, InspectsEmptyPacket) {
  const uint8_t kInput[] = {};

  const auto result =
      InspectPacketForRouting(absl::Span<const uint8_t>(kInput, 0));
  EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
}

// Tests that a packet with garbage is classified as unknown.
TEST(PacketUtilTest, InspectsGarbagePacket) {
  // clang-format off
  const uint8_t kInput[] = {
    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
  };
  // clang-format on

  const auto result = InspectPacketForRouting(kInput);
  EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
}

}  // namespace
}  // namespace cast
}  // namespace openscreen
