/*
 *  Copyright (c) 2012 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.
 */

/*
 * Test application for core FEC algorithm. Calls encoding and decoding
 * functions in ForwardErrorCorrection directly.
 */

#include <string.h>
#include <time.h>

#include <list>

#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/forward_error_correction.h"
#include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
#include "rtc_base/random.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

// #define VERBOSE_OUTPUT

namespace webrtc {
namespace fec_private_tables {
extern const uint8_t** kPacketMaskBurstyTbl[12];
}
namespace test {
using fec_private_tables::kPacketMaskBurstyTbl;

void ReceivePackets(
    std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>*
        to_decode_list,
    std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>*
        received_packet_list,
    size_t num_packets_to_decode,
    float reorder_rate,
    float duplicate_rate,
    Random* random) {
  RTC_DCHECK(to_decode_list->empty());
  RTC_DCHECK_LE(num_packets_to_decode, received_packet_list->size());

  for (size_t i = 0; i < num_packets_to_decode; i++) {
    auto it = received_packet_list->begin();
    // Reorder packets.
    float random_variable = random->Rand<float>();
    while (random_variable < reorder_rate) {
      ++it;
      if (it == received_packet_list->end()) {
        --it;
        break;
      }
      random_variable = random->Rand<float>();
    }
    to_decode_list->push_back(std::move(*it));
    received_packet_list->erase(it);

    // Duplicate packets.
    ForwardErrorCorrection::ReceivedPacket* received_packet =
        to_decode_list->back().get();
    random_variable = random->Rand<float>();
    while (random_variable < duplicate_rate) {
      std::unique_ptr<ForwardErrorCorrection::ReceivedPacket> duplicate_packet(
          new ForwardErrorCorrection::ReceivedPacket());
      *duplicate_packet = *received_packet;
      duplicate_packet->pkt = new ForwardErrorCorrection::Packet();
      memcpy(duplicate_packet->pkt->data, received_packet->pkt->data,
             received_packet->pkt->length);
      duplicate_packet->pkt->length = received_packet->pkt->length;

      to_decode_list->push_back(std::move(duplicate_packet));
      random_variable = random->Rand<float>();
    }
  }
}

void RunTest(bool use_flexfec) {
  // TODO(marpan): Split this function into subroutines/helper functions.
  enum { kMaxNumberMediaPackets = 48 };
  enum { kMaxNumberFecPackets = 48 };

  const uint32_t kNumMaskBytesL0 = 2;
  const uint32_t kNumMaskBytesL1 = 6;

  // FOR UEP
  const bool kUseUnequalProtection = true;

  // FEC mask types.
  const FecMaskType kMaskTypes[] = {kFecMaskRandom, kFecMaskBursty};
  const int kNumFecMaskTypes = sizeof(kMaskTypes) / sizeof(*kMaskTypes);

  // Maximum number of media packets allowed for the mask type.
  const uint16_t kMaxMediaPackets[] = {
      kMaxNumberMediaPackets,
      sizeof(kPacketMaskBurstyTbl) / sizeof(*kPacketMaskBurstyTbl)};

  ASSERT_EQ(12, kMaxMediaPackets[1]) << "Max media packets for bursty mode not "
                                     << "equal to 12.";

  ForwardErrorCorrection::PacketList media_packet_list;
  std::list<ForwardErrorCorrection::Packet*> fec_packet_list;
  std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>
      to_decode_list;
  std::vector<std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>>
      received_packet_list;
  ForwardErrorCorrection::RecoveredPacketList recovered_packet_list;
  std::list<uint8_t*> fec_mask_list;

  // Running over only two loss rates to limit execution time.
  const float loss_rate[] = {0.05f, 0.01f};
  const uint32_t loss_rate_size = sizeof(loss_rate) / sizeof(*loss_rate);
  const float reorder_rate = 0.1f;
  const float duplicate_rate = 0.1f;

  uint8_t media_loss_mask[kMaxNumberMediaPackets];
  uint8_t fec_loss_mask[kMaxNumberFecPackets];
  uint8_t fec_packet_masks[kMaxNumberFecPackets][kMaxNumberMediaPackets];

  // Seed the random number generator, storing the seed to file in order to
  // reproduce past results.
  const unsigned int random_seed = static_cast<unsigned int>(time(nullptr));
  Random random(random_seed);
  std::string filename = webrtc::test::OutputPath() + "randomSeedLog.txt";
  FILE* random_seed_file = fopen(filename.c_str(), "a");
  fprintf(random_seed_file, "%u\n", random_seed);
  fclose(random_seed_file);
  random_seed_file = nullptr;

  uint16_t seq_num = 0;
  uint32_t timestamp = random.Rand<uint32_t>();
  const uint32_t media_ssrc = random.Rand(1u, 0xfffffffe);
  uint32_t fec_ssrc;
  uint16_t fec_seq_num_offset;
  if (use_flexfec) {
    fec_ssrc = random.Rand(1u, 0xfffffffe);
    fec_seq_num_offset = random.Rand(0, 1 << 15);
  } else {
    fec_ssrc = media_ssrc;
    fec_seq_num_offset = 0;
  }

  std::unique_ptr<ForwardErrorCorrection> fec;
  if (use_flexfec) {
    fec = ForwardErrorCorrection::CreateFlexfec(fec_ssrc, media_ssrc);
  } else {
    RTC_DCHECK_EQ(media_ssrc, fec_ssrc);
    fec = ForwardErrorCorrection::CreateUlpfec(fec_ssrc);
  }

  // Loop over the mask types: random and bursty.
  for (int mask_type_idx = 0; mask_type_idx < kNumFecMaskTypes;
       ++mask_type_idx) {
    for (uint32_t loss_rate_idx = 0; loss_rate_idx < loss_rate_size;
         ++loss_rate_idx) {
      printf("Loss rate: %.2f, Mask type %d \n", loss_rate[loss_rate_idx],
             mask_type_idx);

      const uint32_t packet_mask_max = kMaxMediaPackets[mask_type_idx];
      std::unique_ptr<uint8_t[]> packet_mask(
          new uint8_t[packet_mask_max * kNumMaskBytesL1]);

      FecMaskType fec_mask_type = kMaskTypes[mask_type_idx];

      for (uint32_t num_media_packets = 1; num_media_packets <= packet_mask_max;
           num_media_packets++) {
        internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets);

        for (uint32_t num_fec_packets = 1;
             num_fec_packets <= num_media_packets &&
             num_fec_packets <= packet_mask_max;
             num_fec_packets++) {
          // Loop over num_imp_packets: usually <= (0.3*num_media_packets).
          // For this test we check up to ~ (num_media_packets / 4).
          uint32_t max_num_imp_packets = num_media_packets / 4 + 1;
          for (uint32_t num_imp_packets = 0;
               num_imp_packets <= max_num_imp_packets &&
               num_imp_packets <= packet_mask_max;
               num_imp_packets++) {
            uint8_t protection_factor =
                static_cast<uint8_t>(num_fec_packets * 255 / num_media_packets);

            const uint32_t mask_bytes_per_fec_packet =
                (num_media_packets > 16) ? kNumMaskBytesL1 : kNumMaskBytesL0;

            memset(packet_mask.get(), 0,
                   num_media_packets * mask_bytes_per_fec_packet);

            // Transfer packet masks from bit-mask to byte-mask.
            internal::GeneratePacketMasks(
                num_media_packets, num_fec_packets, num_imp_packets,
                kUseUnequalProtection, &mask_table, packet_mask.get());

#ifdef VERBOSE_OUTPUT
            printf(
                "%u media packets, %u FEC packets, %u num_imp_packets, "
                "loss rate = %.2f \n",
                num_media_packets, num_fec_packets, num_imp_packets,
                loss_rate[loss_rate_idx]);
            printf("Packet mask matrix \n");
#endif

            for (uint32_t i = 0; i < num_fec_packets; i++) {
              for (uint32_t j = 0; j < num_media_packets; j++) {
                const uint8_t byte_mask =
                    packet_mask[i * mask_bytes_per_fec_packet + j / 8];
                const uint32_t bit_position = (7 - j % 8);
                fec_packet_masks[i][j] =
                    (byte_mask & (1 << bit_position)) >> bit_position;
#ifdef VERBOSE_OUTPUT
                printf("%u ", fec_packet_masks[i][j]);
#endif
              }
#ifdef VERBOSE_OUTPUT
              printf("\n");
#endif
            }
#ifdef VERBOSE_OUTPUT
            printf("\n");
#endif
            // Check for all zero rows or columns: indicates incorrect mask.
            uint32_t row_limit = num_media_packets;
            for (uint32_t i = 0; i < num_fec_packets; ++i) {
              uint32_t row_sum = 0;
              for (uint32_t j = 0; j < row_limit; ++j) {
                row_sum += fec_packet_masks[i][j];
              }
              ASSERT_NE(0u, row_sum) << "Row is all zero " << i;
            }
            for (uint32_t j = 0; j < row_limit; ++j) {
              uint32_t column_sum = 0;
              for (uint32_t i = 0; i < num_fec_packets; ++i) {
                column_sum += fec_packet_masks[i][j];
              }
              ASSERT_NE(0u, column_sum) << "Column is all zero " << j;
            }

            // Construct media packets.
            // Reset the sequence number here for each FEC code/mask tested
            // below, to avoid sequence number wrap-around. In actual decoding,
            // old FEC packets in list are dropped if sequence number wrap
            // around is detected. This case is currently not handled below.
            seq_num = 0;
            for (uint32_t i = 0; i < num_media_packets; ++i) {
              std::unique_ptr<ForwardErrorCorrection::Packet> media_packet(
                  new ForwardErrorCorrection::Packet());
              const uint32_t kMinPacketSize = 12;
              const uint32_t kMaxPacketSize = static_cast<uint32_t>(
                  IP_PACKET_SIZE - 12 - 28 - fec->MaxPacketOverhead());
              media_packet->length =
                  random.Rand(kMinPacketSize, kMaxPacketSize);

              // Generate random values for the first 2 bytes.
              media_packet->data[0] = random.Rand<uint8_t>();
              media_packet->data[1] = random.Rand<uint8_t>();

              // The first two bits are assumed to be 10 by the
              // FEC encoder. In fact the FEC decoder will set the
              // two first bits to 10 regardless of what they
              // actually were. Set the first two bits to 10
              // so that a memcmp can be performed for the
              // whole restored packet.
              media_packet->data[0] |= 0x80;
              media_packet->data[0] &= 0xbf;

              // FEC is applied to a whole frame.
              // A frame is signaled by multiple packets without
              // the marker bit set followed by the last packet of
              // the frame for which the marker bit is set.
              // Only push one (fake) frame to the FEC.
              media_packet->data[1] &= 0x7f;

              ByteWriter<uint16_t>::WriteBigEndian(&media_packet->data[2],
                                                   seq_num);
              ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[4],
                                                   timestamp);
              ByteWriter<uint32_t>::WriteBigEndian(&media_packet->data[8],
                                                   media_ssrc);
              // Generate random values for payload
              for (size_t j = 12; j < media_packet->length; ++j) {
                media_packet->data[j] = random.Rand<uint8_t>();
              }
              media_packet_list.push_back(std::move(media_packet));
              seq_num++;
            }
            media_packet_list.back()->data[1] |= 0x80;

            ASSERT_EQ(0, fec->EncodeFec(media_packet_list, protection_factor,
                                        num_imp_packets, kUseUnequalProtection,
                                        fec_mask_type, &fec_packet_list))
                << "EncodeFec() failed";

            ASSERT_EQ(num_fec_packets, fec_packet_list.size())
                << "We requested " << num_fec_packets << " FEC packets, but "
                << "EncodeFec() produced " << fec_packet_list.size();

            memset(media_loss_mask, 0, sizeof(media_loss_mask));
            uint32_t media_packet_idx = 0;
            for (const auto& media_packet : media_packet_list) {
              // We want a value between 0 and 1.
              const float loss_random_variable = random.Rand<float>();

              if (loss_random_variable >= loss_rate[loss_rate_idx]) {
                media_loss_mask[media_packet_idx] = 1;
                std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>
                    received_packet(
                        new ForwardErrorCorrection::ReceivedPacket());
                received_packet->pkt = new ForwardErrorCorrection::Packet();
                received_packet->pkt->length = media_packet->length;
                memcpy(received_packet->pkt->data, media_packet->data,
                       media_packet->length);
                received_packet->ssrc = media_ssrc;
                received_packet->seq_num =
                    ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]);
                received_packet->is_fec = false;
                received_packet_list.push_back(std::move(received_packet));
              }
              media_packet_idx++;
            }

            memset(fec_loss_mask, 0, sizeof(fec_loss_mask));
            uint32_t fec_packet_idx = 0;
            for (auto* fec_packet : fec_packet_list) {
              const float loss_random_variable = random.Rand<float>();
              if (loss_random_variable >= loss_rate[loss_rate_idx]) {
                fec_loss_mask[fec_packet_idx] = 1;
                std::unique_ptr<ForwardErrorCorrection::ReceivedPacket>
                    received_packet(
                        new ForwardErrorCorrection::ReceivedPacket());
                received_packet->pkt = new ForwardErrorCorrection::Packet();
                received_packet->pkt->length = fec_packet->length;
                memcpy(received_packet->pkt->data, fec_packet->data,
                       fec_packet->length);
                received_packet->seq_num = fec_seq_num_offset + seq_num;
                received_packet->is_fec = true;
                received_packet->ssrc = fec_ssrc;
                received_packet_list.push_back(std::move(received_packet));

                fec_mask_list.push_back(fec_packet_masks[fec_packet_idx]);
              }
              ++fec_packet_idx;
              ++seq_num;
            }

#ifdef VERBOSE_OUTPUT
            printf("Media loss mask:\n");
            for (uint32_t i = 0; i < num_media_packets; i++) {
              printf("%u ", media_loss_mask[i]);
            }
            printf("\n\n");

            printf("FEC loss mask:\n");
            for (uint32_t i = 0; i < num_fec_packets; i++) {
              printf("%u ", fec_loss_mask[i]);
            }
            printf("\n\n");
#endif

            auto fec_mask_it = fec_mask_list.begin();
            while (fec_mask_it != fec_mask_list.end()) {
              uint32_t hamming_dist = 0;
              uint32_t recovery_position = 0;
              for (uint32_t i = 0; i < num_media_packets; i++) {
                if (media_loss_mask[i] == 0 && (*fec_mask_it)[i] == 1) {
                  recovery_position = i;
                  ++hamming_dist;
                }
              }
              auto item_to_delete = fec_mask_it;
              ++fec_mask_it;

              if (hamming_dist == 1) {
                // Recovery possible. Restart search.
                media_loss_mask[recovery_position] = 1;
                fec_mask_it = fec_mask_list.begin();
              } else if (hamming_dist == 0) {
                // FEC packet cannot provide further recovery.
                fec_mask_list.erase(item_to_delete);
              }
            }
#ifdef VERBOSE_OUTPUT
            printf("Recovery mask:\n");
            for (uint32_t i = 0; i < num_media_packets; ++i) {
              printf("%u ", media_loss_mask[i]);
            }
            printf("\n\n");
#endif
            // For error-checking frame completion.
            bool fec_packet_received = false;
            while (!received_packet_list.empty()) {
              size_t num_packets_to_decode = random.Rand(
                  1u, static_cast<uint32_t>(received_packet_list.size()));
              ReceivePackets(&to_decode_list, &received_packet_list,
                             num_packets_to_decode, reorder_rate,
                             duplicate_rate, &random);

              if (fec_packet_received == false) {
                for (const auto& received_packet : to_decode_list) {
                  if (received_packet->is_fec) {
                    fec_packet_received = true;
                  }
                }
              }
              for (const auto& received_packet : to_decode_list) {
                fec->DecodeFec(*received_packet, &recovered_packet_list);
              }
              to_decode_list.clear();
            }
            media_packet_idx = 0;
            for (const auto& media_packet : media_packet_list) {
              if (media_loss_mask[media_packet_idx] == 1) {
                // Should have recovered this packet.
                auto recovered_packet_list_it = recovered_packet_list.cbegin();

                ASSERT_FALSE(recovered_packet_list_it ==
                             recovered_packet_list.end())
                    << "Insufficient number of recovered packets.";
                ForwardErrorCorrection::RecoveredPacket* recovered_packet =
                    recovered_packet_list_it->get();

                ASSERT_EQ(recovered_packet->pkt->length, media_packet->length)
                    << "Recovered packet length not identical to original "
                    << "media packet";
                ASSERT_EQ(0, memcmp(recovered_packet->pkt->data,
                                    media_packet->data, media_packet->length))
                    << "Recovered packet payload not identical to original "
                    << "media packet";
                recovered_packet_list.pop_front();
              }
              ++media_packet_idx;
            }
            fec->ResetState(&recovered_packet_list);
            ASSERT_TRUE(recovered_packet_list.empty())
                << "Excessive number of recovered packets.\t size is: "
                << recovered_packet_list.size();
            // -- Teardown --
            media_packet_list.clear();

            // Clear FEC packet list, so we don't pass in a non-empty
            // list in the next call to DecodeFec().
            fec_packet_list.clear();

            // Delete received packets we didn't pass to DecodeFec(), due to
            // early frame completion.
            received_packet_list.clear();

            while (!fec_mask_list.empty()) {
              fec_mask_list.pop_front();
            }
            timestamp += 90000 / 30;
          }  // loop over num_imp_packets
        }    // loop over FecPackets
      }      // loop over num_media_packets
    }        // loop over loss rates
  }          // loop over mask types

  // Have DecodeFec clear the recovered packet list.
  fec->ResetState(&recovered_packet_list);
  ASSERT_TRUE(recovered_packet_list.empty())
      << "Recovered packet list is not empty";
}

TEST(FecTest, UlpfecTest) {
  RunTest(false);
}

TEST(FecTest, FlexfecTest) {
  RunTest(true);
}

}  // namespace test
}  // namespace webrtc
