/*
 *  Copyright (c) 2011 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 "modules/video_coding/codecs/test/packet_manipulator.h"

#include <queue>

#include "gtest/gtest.h"
#include "modules/video_coding/codecs/interface/video_codec_interface.h"
#include "testsupport/unittest_utils.h"
#include "typedefs.h"

namespace webrtc {
namespace test {

const double kNeverDropProbability = 0.0;
const double kAlwaysDropProbability = 1.0;
const int kBurstLength = 1;

class PacketManipulatorTest: public PacketRelatedTest {
 protected:
  PacketReader packet_reader_;
  EncodedImage image_;
  NetworkingConfig drop_config_;
  NetworkingConfig no_drop_config_;

  PacketManipulatorTest() {
    image_._buffer = packet_data_;
    image_._length = kPacketDataLength;
    image_._size = kPacketDataLength;

    drop_config_.packet_size_in_bytes = kPacketSizeInBytes;
    drop_config_.packet_loss_probability = kAlwaysDropProbability;
    drop_config_.packet_loss_burst_length = kBurstLength;
    drop_config_.packet_loss_mode = kUniform;

    no_drop_config_.packet_size_in_bytes = kPacketSizeInBytes;
    no_drop_config_.packet_loss_probability = kNeverDropProbability;
    no_drop_config_.packet_loss_burst_length = kBurstLength;
    no_drop_config_.packet_loss_mode = kUniform;
  }

  virtual ~PacketManipulatorTest() {}

  void SetUp() {
    PacketRelatedTest::SetUp();
  }

  void TearDown() {
    PacketRelatedTest::TearDown();
  }

  void VerifyPacketLoss(int expected_nbr_packets_dropped,
                        int actual_nbr_packets_dropped,
                        int expected_packet_data_length,
                        WebRtc_UWord8* expected_packet_data,
                        EncodedImage& actual_image) {
    EXPECT_EQ(expected_nbr_packets_dropped, actual_nbr_packets_dropped);
    EXPECT_EQ(expected_packet_data_length, static_cast<int>(image_._length));
    EXPECT_EQ(0, memcmp(expected_packet_data, actual_image._buffer,
                        expected_packet_data_length));
  }
};

// Predictive packet manipulator that allows for setup of the result of
// the random invocations.
class PredictivePacketManipulatorImpl : public PacketManipulatorImpl {
 public:
  PredictivePacketManipulatorImpl(PacketReader* packet_reader,
                                  const NetworkingConfig& config)
    : PacketManipulatorImpl(packet_reader, config, false) {
  }
  // Adds a result. You must add at least the same number of results as the
  // expected calls to the RandomUniform method. The results are added to a
  // FIFO queue so they will be returned in the same order they were added.
  void AddRandomResult(double result) {
    ASSERT_TRUE(result >= 0.0 || result <= 1.0)
        << "Cannot add results outside the range 0.0 - 1.0, was:" << result;
    random_results_.push(result);
  }
 protected:
  double RandomUniform() {
    EXPECT_GT(random_results_.size(), 0u) << "No more stored results, please "
        "make sure AddRandomResult() is called same amount of times you're "
        "going to invoke the RandomUniform() function, i.e. once per packet.";
    double result = random_results_.front();
    random_results_.pop();
    return result;
  }
 private:
  std::queue<double> random_results_;
};

TEST_F(PacketManipulatorTest, Constructor) {
  PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false);
}

TEST_F(PacketManipulatorTest, DropNone) {
  PacketManipulatorImpl manipulator(&packet_reader_,  no_drop_config_, false);
  int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);
  VerifyPacketLoss(0, nbr_packets_dropped, kPacketDataLength,
                   packet_data_, image_);
}

TEST_F(PacketManipulatorTest, UniformDropNoneSmallFrame) {
  int data_length = 400;  // smaller than the packet size
  image_._length = data_length;
  PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false);
  int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);

  VerifyPacketLoss(0, nbr_packets_dropped, data_length,
                     packet_data_, image_);
}

TEST_F(PacketManipulatorTest, UniformDropAll) {
  PacketManipulatorImpl manipulator(&packet_reader_, drop_config_, false);
  int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);
  VerifyPacketLoss(kPacketDataNumberOfPackets, nbr_packets_dropped,
                   0, packet_data_, image_);
}

// Use our customized test class to make the second packet being lost
TEST_F(PacketManipulatorTest, UniformDropSinglePacket) {
  drop_config_.packet_loss_probability = 0.5;
  PredictivePacketManipulatorImpl manipulator(&packet_reader_, drop_config_);
  manipulator.AddRandomResult(1.0);
  manipulator.AddRandomResult(0.3);  // less than 0.5 will cause packet loss
  manipulator.AddRandomResult(1.0);

  // Execute the test target method:
  int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);

  // Since we setup the predictive packet manipulator, it will throw away the
  // second packet. The third packet is also lost because when we have lost one,
  // the remains shall also be discarded (in the current implementation).
  VerifyPacketLoss(2, nbr_packets_dropped, kPacketSizeInBytes, packet1_,
                   image_);
}

// Use our customized test class to make the second packet being lost
TEST_F(PacketManipulatorTest, BurstDropNinePackets) {
  // Create a longer packet data structure (10 packets)
  const int kNbrPackets = 10;
  const int kDataLength = kPacketSizeInBytes * kNbrPackets;
  WebRtc_UWord8 data[kDataLength];
  WebRtc_UWord8* data_pointer = data;
  // Fill with 0s, 1s and so on to be able to easily verify which were dropped:
  for (int i = 0; i < kNbrPackets; ++i) {
    memset(data_pointer + i * kPacketSizeInBytes, i, kPacketSizeInBytes);
  }
  // Overwrite the defaults from the test fixture:
  image_._buffer = data;
  image_._length = kDataLength;
  image_._size = kDataLength;

  drop_config_.packet_loss_probability = 0.5;
  drop_config_.packet_loss_burst_length = 5;
  drop_config_.packet_loss_mode = kBurst;
  PredictivePacketManipulatorImpl manipulator(&packet_reader_, drop_config_);
  manipulator.AddRandomResult(1.0);
  manipulator.AddRandomResult(0.3);  // less than 0.5 will cause packet loss
  for (int i = 0; i < kNbrPackets - 2; ++i) {
    manipulator.AddRandomResult(1.0);
  }

  // Execute the test target method:
  int nbr_packets_dropped = manipulator.ManipulatePackets(&image_);

  // Should discard every packet after the first one.
  VerifyPacketLoss(9, nbr_packets_dropped, kPacketSizeInBytes, data, image_);
}

}  // namespace test
}  // namespace webrtc
