/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <algorithm>
#include <memory>

#include "webrtc/base/basictypes.h"
#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"

namespace webrtc {

namespace {

using ::testing::_;
using ::testing::Args;
using ::testing::ElementsAreArray;
using ::testing::Return;

using test::fec::FlexfecPacketGenerator;
using Packet = ForwardErrorCorrection::Packet;
using PacketList = ForwardErrorCorrection::PacketList;

constexpr size_t kPayloadLength = 500;
constexpr uint32_t kFlexfecSsrc = 42984;
constexpr uint32_t kMediaSsrc = 8353;

}  // namespace

class FlexfecReceiverTest : public ::testing::Test {
 protected:
  FlexfecReceiverTest()
      : receiver_(kFlexfecSsrc, kMediaSsrc, &recovered_packet_receiver_),
        erasure_code_(ForwardErrorCorrection::CreateFlexfec()),
        packet_generator_(kMediaSsrc, kFlexfecSsrc) {}

  // Generates |num_media_packets| corresponding to a single frame.
  void PacketizeFrame(size_t num_media_packets,
                      size_t frame_offset,
                      PacketList* media_packets);

  // Generates |num_fec_packets| FEC packets, given |media_packets|.
  std::list<Packet*> EncodeFec(const PacketList& media_packets,
                               size_t num_fec_packets);

  FlexfecReceiver receiver_;
  std::unique_ptr<ForwardErrorCorrection> erasure_code_;

  FlexfecPacketGenerator packet_generator_;
  testing::StrictMock<MockRecoveredPacketReceiver> recovered_packet_receiver_;
};

void FlexfecReceiverTest::PacketizeFrame(size_t num_media_packets,
                                         size_t frame_offset,
                                         PacketList* media_packets) {
  packet_generator_.NewFrame(num_media_packets);
  for (size_t i = 0; i < num_media_packets; ++i) {
    std::unique_ptr<Packet> next_packet(
        packet_generator_.NextPacket(frame_offset + i, kPayloadLength));
    media_packets->push_back(std::move(next_packet));
  }
}

std::list<Packet*> FlexfecReceiverTest::EncodeFec(
    const PacketList& media_packets,
    size_t num_fec_packets) {
  const uint8_t protection_factor =
      num_fec_packets * 255 / media_packets.size();
  constexpr int kNumImportantPackets = 0;
  constexpr bool kUseUnequalProtection = false;
  constexpr FecMaskType kFecMaskType = kFecMaskRandom;
  std::list<Packet*> fec_packets;
  EXPECT_EQ(0, erasure_code_->EncodeFec(
                   media_packets, protection_factor, kNumImportantPackets,
                   kUseUnequalProtection, kFecMaskType, &fec_packets));
  EXPECT_EQ(num_fec_packets, fec_packets.size());
  return fec_packets;
}

TEST_F(FlexfecReceiverTest, ReceivesMediaPacket) {
  packet_generator_.NewFrame(1);
  std::unique_ptr<Packet> media_packet(
      packet_generator_.NextPacket(0, kPayloadLength));

  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                    media_packet->length));
}

TEST_F(FlexfecReceiverTest, FailsOnTruncatedMediaPacket) {
  const size_t kNoPayload = 0;

  packet_generator_.NewFrame(1);
  std::unique_ptr<Packet> media_packet(
      packet_generator_.NextPacket(0, kNoPayload));
  // Simulate truncated media packet.
  media_packet->length = kRtpHeaderSize - 1;

  EXPECT_FALSE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                     media_packet->length));
}

TEST_F(FlexfecReceiverTest, ReceivesMediaAndFecPackets) {
  const size_t kNumMediaPackets = 1;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);
  auto media_packet = media_packets.front().get();
  auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front());

  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                    media_packet->length));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(fec_packet->data,
                                                    fec_packet->length));
}

TEST_F(FlexfecReceiverTest, FailsOnTruncatedFecPacket) {
  const size_t kNumMediaPackets = 1;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);
  auto media_packet = media_packets.front().get();
  // Simulate truncated FlexFEC payload.
  fec_packets.front()->length = 1;
  auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front());

  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                    media_packet->length));
  EXPECT_FALSE(receiver_.AddAndProcessReceivedPacket(fec_packet->data,
                                                     fec_packet->length));
}

TEST_F(FlexfecReceiverTest, FailsOnUnknownMediaSsrc) {
  const size_t kNumMediaPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  auto media_packet = media_packets.front().get();
  // Corrupt the SSRC.
  media_packet->data[8] = 0;
  media_packet->data[9] = 1;
  media_packet->data[10] = 2;
  media_packet->data[11] = 3;

  EXPECT_FALSE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                     media_packet->length));
}

TEST_F(FlexfecReceiverTest, FailsOnUnknownFecSsrc) {
  const size_t kNumMediaPackets = 1;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);
  auto media_packet = media_packets.front().get();
  auto fec_packet = packet_generator_.BuildFlexfecPacket(*fec_packets.front());
  // Corrupt the SSRC.
  fec_packet->data[8] = 4;
  fec_packet->data[9] = 5;
  fec_packet->data[10] = 6;
  fec_packet->data[11] = 7;

  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                    media_packet->length));
  EXPECT_FALSE(receiver_.AddAndProcessReceivedPacket(fec_packet->data,
                                                     fec_packet->length));
}

TEST_F(FlexfecReceiverTest, ReceivesMultiplePackets) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Receive all media packets.
  for (const auto& media_packet : media_packets) {
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(media_packet->data,
                                                      media_packet->length));
  }

  // Receive FEC packet.
  auto fec_packet = fec_packets.front();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(*fec_packet);
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));
}

TEST_F(FlexfecReceiverTest, RecoversFromSingleMediaLoss) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Receive first media packet but drop second.
  auto media_it = media_packets.begin();
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                    (*media_it)->length));

  // Receive FEC packet and ensure recovery of lost media packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  media_it++;
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));
}

TEST_F(FlexfecReceiverTest, RecoversFromDoubleMediaLoss) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 2;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Drop both media packets.

  // Receive first FEC packet and recover first lost media packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  auto media_it = media_packets.begin();
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));

  // Receive second FEC packet and recover second lost media packet.
  fec_it++;
  packet_with_rtp_header = packet_generator_.BuildFlexfecPacket(**fec_it);
  media_it++;
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));
}

TEST_F(FlexfecReceiverTest, DoesNotRecoverFromMediaAndFecLoss) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Receive first media packet.
  auto media_it = media_packets.begin();
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                    (*media_it)->length));

  // Drop second media packet and FEC packet. Do not expect call back.
}

TEST_F(FlexfecReceiverTest, DoesNotCallbackTwice) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Receive first media packet but drop second.
  auto media_it = media_packets.begin();
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                    (*media_it)->length));

  // Receive FEC packet and ensure recovery of lost media packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  media_it++;
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));

  // Receive FEC packet again.
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));

  // Do not call back again.
}

// Here we are implicitly assuming packet masks that are suitable for
// this type of 50% correlated loss. If we are changing our precomputed
// packet masks, this test might need to be updated.
TEST_F(FlexfecReceiverTest, RecoversFrom50PercentLoss) {
  const size_t kNumFecPackets = 5;
  const size_t kNumFrames = 2 * kNumFecPackets;
  const size_t kNumMediaPacketsPerFrame = 1;

  PacketList media_packets;
  for (size_t i = 0; i < kNumFrames; ++i) {
    PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets);
  }
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Drop every second media packet.
  auto media_it = media_packets.begin();
  while (media_it != media_packets.end()) {
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                      (*media_it)->length));
    ++media_it;
    if (media_it == media_packets.end()) {
      break;
    }
    ++media_it;
  }

  // Receive all FEC packets.
  media_it = media_packets.begin();
  for (const auto& fec_packet : fec_packets) {
    std::unique_ptr<Packet> fec_packet_with_rtp_header =
        packet_generator_.BuildFlexfecPacket(*fec_packet);
    ++media_it;
    if (media_it == media_packets.end()) {
      break;
    }
    EXPECT_CALL(recovered_packet_receiver_,
                OnRecoveredPacket(_, (*media_it)->length))
        .With(Args<0, 1>(
            ElementsAreArray((*media_it)->data, (*media_it)->length)))
        .WillOnce(Return(true));
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
        fec_packet_with_rtp_header->data, fec_packet_with_rtp_header->length));
    ++media_it;
  }
}

TEST_F(FlexfecReceiverTest, DelayedFecPacketDoesHelp) {
  // These values need to be updated if the underlying erasure code
  // implementation changes.
  const size_t kNumFrames = 48;
  const size_t kNumMediaPacketsPerFrame = 1;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPacketsPerFrame, 0, &media_packets);
  PacketizeFrame(kNumMediaPacketsPerFrame, 1, &media_packets);
  // Protect two first frames.
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);
  for (size_t i = 2; i < kNumFrames; ++i) {
    PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets);
  }

  // Drop first media packet and delay FEC packet.
  auto media_it = media_packets.begin();
  ++media_it;

  // Receive all other media packets.
  while (media_it != media_packets.end()) {
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                      (*media_it)->length));
    ++media_it;
  }

  // Receive FEC packet and recover first media packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  media_it = media_packets.begin();
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));
}

TEST_F(FlexfecReceiverTest, TooDelayedFecPacketDoesNotHelp) {
  // These values need to be updated if the underlying erasure code
  // implementation changes.
  const size_t kNumFrames = 49;
  const size_t kNumMediaPacketsPerFrame = 1;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPacketsPerFrame, 0, &media_packets);
  PacketizeFrame(kNumMediaPacketsPerFrame, 1, &media_packets);
  // Protect two first frames.
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);
  for (size_t i = 2; i < kNumFrames; ++i) {
    PacketizeFrame(kNumMediaPacketsPerFrame, i, &media_packets);
  }

  // Drop first media packet and delay FEC packet.
  auto media_it = media_packets.begin();
  ++media_it;

  // Receive all other media packets.
  while (media_it != media_packets.end()) {
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                      (*media_it)->length));
    ++media_it;
  }

  // Receive FEC packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));

  // Do not expect a call back.
}

TEST_F(FlexfecReceiverTest, RecoversWithMediaPacketsOutOfOrder) {
  const size_t kNumMediaPackets = 6;
  const size_t kNumFecPackets = 2;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Lose two media packets, and receive the others out of order.
  auto media_it = media_packets.begin();
  auto media_packet0 = media_it++;
  auto media_packet1 = media_it++;
  auto media_packet2 = media_it++;
  auto media_packet3 = media_it++;
  auto media_packet4 = media_it++;
  auto media_packet5 = media_it++;
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_packet5)->data,
                                                    (*media_packet5)->length));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_packet2)->data,
                                                    (*media_packet2)->length));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_packet3)->data,
                                                    (*media_packet3)->length));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_packet0)->data,
                                                    (*media_packet0)->length));

  // Expect to recover lost media packets.
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_packet1)->length))
      .With(Args<0, 1>(
          ElementsAreArray((*media_packet1)->data, (*media_packet1)->length)))
      .WillOnce(Return(true));
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_packet4)->length))
      .With(Args<0, 1>(
          ElementsAreArray((*media_packet4)->data, (*media_packet4)->length)))
      .WillOnce(Return(true));

  // Add FEC packets.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header;
  while (fec_it != fec_packets.end()) {
    packet_with_rtp_header = packet_generator_.BuildFlexfecPacket(**fec_it);
    EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
        packet_with_rtp_header->data, packet_with_rtp_header->length));
    ++fec_it;
  }
}

TEST_F(FlexfecReceiverTest, CalculatesNumberOfPackets) {
  const size_t kNumMediaPackets = 2;
  const size_t kNumFecPackets = 1;

  PacketList media_packets;
  PacketizeFrame(kNumMediaPackets, 0, &media_packets);
  std::list<Packet*> fec_packets = EncodeFec(media_packets, kNumFecPackets);

  // Receive first media packet but drop second.
  auto media_it = media_packets.begin();
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket((*media_it)->data,
                                                    (*media_it)->length));

  // Receive FEC packet and ensure recovery of lost media packet.
  auto fec_it = fec_packets.begin();
  std::unique_ptr<Packet> packet_with_rtp_header =
      packet_generator_.BuildFlexfecPacket(**fec_it);
  media_it++;
  EXPECT_CALL(recovered_packet_receiver_,
              OnRecoveredPacket(_, (*media_it)->length))
      .With(
          Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)))
      .WillOnce(Return(true));
  EXPECT_TRUE(receiver_.AddAndProcessReceivedPacket(
      packet_with_rtp_header->data, packet_with_rtp_header->length));

  // Check stats calculations.
  FecPacketCounter packet_counter = receiver_.GetPacketCounter();
  EXPECT_EQ(2U, packet_counter.num_packets);
  EXPECT_EQ(1U, packet_counter.num_fec_packets);
  EXPECT_EQ(1U, packet_counter.num_recovered_packets);
}

}  // namespace webrtc
