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

#ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_
#define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_

#include <list>
#include <map>
#include <utility>
#include <vector>

#include "common_types.h"  // NOLINT(build/include)
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"

namespace webrtc {
namespace testing {
namespace bwe {

class Packet {
 public:
  enum Type { kMedia, kFeedback };

  Packet();
  Packet(int flow_id, int64_t send_time_us, size_t payload_size);
  virtual ~Packet();

  virtual bool operator<(const Packet& rhs) const;

  virtual int flow_id() const;
  virtual void set_send_time_us(int64_t send_time_us);
  virtual int64_t send_time_us() const;
  virtual int64_t sender_timestamp_us() const;
  virtual size_t payload_size() const;
  virtual Packet::Type GetPacketType() const = 0;
  virtual void set_sender_timestamp_us(int64_t sender_timestamp_us);
  virtual int64_t creation_time_ms() const;
  virtual int64_t sender_timestamp_ms() const;
  virtual int64_t send_time_ms() const;

 protected:
  int flow_id_;
  int64_t creation_time_us_;  // Time when the packet was created.
  int64_t send_time_us_;  // Time the packet left last processor touching it.
  int64_t sender_timestamp_us_;  // Time the packet left the Sender.
  size_t payload_size_;  // Size of the (non-existent, simulated) payload.
};

class MediaPacket : public Packet {
 public:
  MediaPacket();
  MediaPacket(int flow_id,
              int64_t send_time_us,
              size_t payload_size,
              uint16_t sequence_number);
  MediaPacket(int flow_id,
              int64_t send_time_us,
              size_t payload_size,
              const RTPHeader& header);
  MediaPacket(int64_t send_time_us, uint16_t sequence_number);

  ~MediaPacket() override {}

  int64_t GetAbsSendTimeInMs() const {
    int64_t timestamp = header_.extension.absoluteSendTime
                        << kAbsSendTimeInterArrivalUpshift;
    return 1000.0 * timestamp / static_cast<double>(1 << kInterArrivalShift);
  }
  void SetAbsSendTimeMs(int64_t abs_send_time_ms);
  const RTPHeader& header() const { return header_; }
  Packet::Type GetPacketType() const override;
  uint16_t sequence_number() const { return header_.sequenceNumber; }
  RtpPacketReceived GetRtpPacket() const;

 private:
  static const int kAbsSendTimeFraction = 18;
  static const int kAbsSendTimeInterArrivalUpshift = 8;
  static const int kInterArrivalShift =
      kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;

  RTPHeader header_;
};

class FeedbackPacket : public Packet {
 public:
  FeedbackPacket(int flow_id,
                 int64_t this_send_time_us,
                 int64_t latest_send_time_ms)
      : Packet(flow_id, this_send_time_us, 0),
        latest_send_time_ms_(latest_send_time_ms) {}
  ~FeedbackPacket() override {}

  Packet::Type GetPacketType() const override;
  int64_t latest_send_time_ms() const { return latest_send_time_ms_; }

 private:
  int64_t latest_send_time_ms_;  // Time stamp for the latest sent FbPacket.
};

class BbrBweFeedback : public FeedbackPacket {
 public:
  BbrBweFeedback(int flow_id,
                 int64_t send_time_us,
                 int64_t latest_send_time_ms,
                 const std::vector<uint16_t>& packet_feedback_vector);
  ~BbrBweFeedback() override;

  const std::vector<uint16_t>& packet_feedback_vector() const {
    return packet_feedback_vector_;
  }

 private:
  const std::vector<uint16_t> packet_feedback_vector_;
};

class RembFeedback : public FeedbackPacket {
 public:
  RembFeedback(int flow_id,
               int64_t send_time_us,
               int64_t latest_send_time_ms,
               uint32_t estimated_bps,
               RTCPReportBlock report_block);
  ~RembFeedback() override {}

  uint32_t estimated_bps() const { return estimated_bps_; }
  RTCPReportBlock report_block() const { return report_block_; }

 private:
  const uint32_t estimated_bps_;
  const RTCPReportBlock report_block_;
};

class SendSideBweFeedback : public FeedbackPacket {
 public:
  typedef std::map<uint16_t, int64_t> ArrivalTimesMap;
  SendSideBweFeedback(
      int flow_id,
      int64_t send_time_us,
      int64_t latest_send_time_ms,
      const std::vector<PacketFeedback>& packet_feedback_vector);
  ~SendSideBweFeedback() override;

  const std::vector<PacketFeedback>& packet_feedback_vector() const {
    return packet_feedback_vector_;
  }

 private:
  const std::vector<PacketFeedback> packet_feedback_vector_;
};

class NadaFeedback : public FeedbackPacket {
 public:
  NadaFeedback(int flow_id,
               int64_t this_send_time_us,
               int64_t exp_smoothed_delay_ms,
               int64_t est_queuing_delay_signal_ms,
               int64_t congestion_signal,
               float derivative,
               float receiving_rate,
               int64_t latest_send_time_ms)
      : FeedbackPacket(flow_id, this_send_time_us, latest_send_time_ms),
        exp_smoothed_delay_ms_(exp_smoothed_delay_ms),
        est_queuing_delay_signal_ms_(est_queuing_delay_signal_ms),
        congestion_signal_(congestion_signal),
        derivative_(derivative),
        receiving_rate_(receiving_rate) {}
  ~NadaFeedback() override {}

  int64_t exp_smoothed_delay_ms() const { return exp_smoothed_delay_ms_; }
  int64_t est_queuing_delay_signal_ms() const {
    return est_queuing_delay_signal_ms_;
  }
  int64_t congestion_signal() const { return congestion_signal_; }
  float derivative() const { return derivative_; }
  float receiving_rate() const { return receiving_rate_; }

 private:
  int64_t exp_smoothed_delay_ms_;        // Referred as d_hat_n.
  int64_t est_queuing_delay_signal_ms_;  // Referred as d_tilde_n.
  int64_t congestion_signal_;            // Referred as x_n.
  float derivative_;                     // Referred as x'_n.
  float receiving_rate_;                 // Referred as R_r.
};

class TcpFeedback : public FeedbackPacket {
 public:
  TcpFeedback(int flow_id,
              int64_t send_time_us,
              int64_t latest_send_time_ms,
              const std::vector<uint16_t>& acked_packets);
  ~TcpFeedback() override;

  const std::vector<uint16_t>& acked_packets() const { return acked_packets_; }

 private:
  const std::vector<uint16_t> acked_packets_;
};

typedef std::list<Packet*> Packets;
typedef std::list<Packet*>::iterator PacketsIt;
typedef std::list<Packet*>::const_iterator PacketsConstIt;

}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
#endif  // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_PACKET_H_
