/*
 *  Copyright (c) 2014 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 WEBRTC_VIDEO_RAMPUP_TESTS_H_
#define WEBRTC_VIDEO_RAMPUP_TESTS_H_

#include <map>
#include <string>
#include <vector>

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/call.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/test/call_test.h"
#include "webrtc/video/transport_adapter.h"

namespace webrtc {

static const int kTransmissionTimeOffsetExtensionId = 6;
static const int kAbsSendTimeExtensionId = 7;
static const unsigned int kSingleStreamTargetBps = 1000000;

class Clock;
class ReceiveStatistics;
class RtpHeaderParser;
class RTPPayloadRegistry;
class RtpRtcp;

class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
 public:
  typedef std::map<uint32_t, int> BytesSentMap;
  typedef std::map<uint32_t, uint32_t> SsrcMap;
  StreamObserver(const SsrcMap& rtx_media_ssrcs,
                 newapi::Transport* feedback_transport,
                 Clock* clock);

  void set_expected_bitrate_bps(unsigned int expected_bitrate_bps);

  void set_start_bitrate_bps(unsigned int start_bitrate_bps);

  void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
                               unsigned int bitrate) override;

  bool SendRtp(const uint8_t* packet, size_t length) override;

  bool SendRtcp(const uint8_t* packet, size_t length) override;

  EventTypeWrapper Wait();

  void SetRemoteBitrateEstimator(RemoteBitrateEstimator* rbe);

 private:
  void ReportResult(const std::string& measurement,
                    size_t value,
                    const std::string& units);
  void TriggerTestDone() EXCLUSIVE_LOCKS_REQUIRED(crit_);

  Clock* const clock_;
  const rtc::scoped_ptr<EventWrapper> test_done_;
  const rtc::scoped_ptr<RtpHeaderParser> rtp_parser_;
  rtc::scoped_ptr<RtpRtcp> rtp_rtcp_;
  internal::TransportAdapter feedback_transport_;
  const rtc::scoped_ptr<ReceiveStatistics> receive_stats_;
  const rtc::scoped_ptr<RTPPayloadRegistry> payload_registry_;
  rtc::scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;

  rtc::CriticalSection crit_;
  unsigned int expected_bitrate_bps_ GUARDED_BY(crit_);
  unsigned int start_bitrate_bps_ GUARDED_BY(crit_);
  SsrcMap rtx_media_ssrcs_ GUARDED_BY(crit_);
  size_t total_sent_ GUARDED_BY(crit_);
  size_t padding_sent_ GUARDED_BY(crit_);
  size_t rtx_media_sent_ GUARDED_BY(crit_);
  int total_packets_sent_ GUARDED_BY(crit_);
  int padding_packets_sent_ GUARDED_BY(crit_);
  int rtx_media_packets_sent_ GUARDED_BY(crit_);
  int64_t test_start_ms_ GUARDED_BY(crit_);
  int64_t ramp_up_finished_ms_ GUARDED_BY(crit_);
};

class LowRateStreamObserver : public test::DirectTransport,
                              public RemoteBitrateObserver,
                              public PacketReceiver {
 public:
  LowRateStreamObserver(newapi::Transport* feedback_transport,
                        Clock* clock,
                        size_t number_of_streams,
                        bool rtx_used);

  virtual void SetSendStream(VideoSendStream* send_stream);

  virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
                                       unsigned int bitrate);

  bool SendRtp(const uint8_t* data, size_t length) override;

  DeliveryStatus DeliverPacket(MediaType media_type,
                               const uint8_t* packet,
                               size_t length,
                               const PacketTime& packet_time) override;

  bool SendRtcp(const uint8_t* packet, size_t length) override;

  // Produces a string similar to "1stream_nortx", depending on the values of
  // number_of_streams_ and rtx_used_;
  std::string GetModifierString();

  // This method defines the state machine for the ramp up-down-up test.
  void EvolveTestState(unsigned int bitrate_bps);

  EventTypeWrapper Wait();

 private:
  static const unsigned int kHighBandwidthLimitBps = 80000;
  static const unsigned int kExpectedHighBitrateBps = 60000;
  static const unsigned int kLowBandwidthLimitBps = 20000;
  static const unsigned int kExpectedLowBitrateBps = 20000;
  enum TestStates { kFirstRampup, kLowRate, kSecondRampup };

  Clock* const clock_;
  const size_t number_of_streams_;
  const bool rtx_used_;
  const rtc::scoped_ptr<EventWrapper> test_done_;
  const rtc::scoped_ptr<RtpHeaderParser> rtp_parser_;
  const rtc::scoped_ptr<RTPPayloadRegistry> payload_registry_;
  rtc::scoped_ptr<RtpRtcp> rtp_rtcp_;
  internal::TransportAdapter feedback_transport_;
  const rtc::scoped_ptr<ReceiveStatistics> receive_stats_;
  rtc::scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;

  rtc::CriticalSection crit_;
  VideoSendStream* send_stream_ GUARDED_BY(crit_);
  FakeNetworkPipe::Config forward_transport_config_ GUARDED_BY(crit_);
  TestStates test_state_ GUARDED_BY(crit_);
  int64_t state_start_ms_ GUARDED_BY(crit_);
  int64_t interval_start_ms_ GUARDED_BY(crit_);
  unsigned int last_remb_bps_ GUARDED_BY(crit_);
  size_t sent_bytes_ GUARDED_BY(crit_);
  size_t total_overuse_bytes_ GUARDED_BY(crit_);
  bool suspended_in_stats_ GUARDED_BY(crit_);
};

class RampUpTest : public test::CallTest {
 protected:
  void RunRampUpTest(size_t num_streams,
                     unsigned int start_bitrate_bps,
                     const std::string& extension_type,
                     bool rtx,
                     bool red);

  void RunRampUpDownUpTest(size_t number_of_streams, bool rtx, bool red);
};
}  // namespace webrtc
#endif  // WEBRTC_VIDEO_RAMPUP_TESTS_H_
