/*
 *  Copyright (c) 2013 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 <assert.h>

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

#include "testing/gtest/include/gtest/gtest.h"

#include "webrtc/call.h"
#include "webrtc/common.h"
#include "webrtc/experiments.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/encoder_settings.h"
#include "webrtc/test/fake_decoder.h"
#include "webrtc/test/fake_encoder.h"
#include "webrtc/test/frame_generator_capturer.h"
#include "webrtc/test/testsupport/perf_test.h"
#include "webrtc/video/transport_adapter.h"

namespace webrtc {

namespace {
static const int kAbsoluteSendTimeExtensionId = 7;
static const int kMaxPacketSize = 1500;

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)
      : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
        test_done_(EventWrapper::Create()),
        rtp_parser_(RtpHeaderParser::Create()),
        feedback_transport_(feedback_transport),
        receive_stats_(ReceiveStatistics::Create(clock)),
        payload_registry_(
            new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(false))),
        clock_(clock),
        expected_bitrate_bps_(0),
        rtx_media_ssrcs_(rtx_media_ssrcs),
        total_sent_(0),
        padding_sent_(0),
        rtx_media_sent_(0),
        total_packets_sent_(0),
        padding_packets_sent_(0),
        rtx_media_packets_sent_(0) {
    // Ideally we would only have to instantiate an RtcpSender, an
    // RtpHeaderParser and a RemoteBitrateEstimator here, but due to the current
    // state of the RTP module we need a full module and receive statistics to
    // be able to produce an RTCP with REMB.
    RtpRtcp::Configuration config;
    config.receive_statistics = receive_stats_.get();
    feedback_transport_.Enable();
    config.outgoing_transport = &feedback_transport_;
    rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
    rtp_rtcp_->SetREMBStatus(true);
    rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
    rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
                                            kAbsoluteSendTimeExtensionId);
    AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
    const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000;
    remote_bitrate_estimator_.reset(
        rbe_factory.Create(this, clock, kMimdControl,
                           kRemoteBitrateEstimatorMinBitrateBps));
  }

  void set_expected_bitrate_bps(unsigned int expected_bitrate_bps) {
    expected_bitrate_bps_ = expected_bitrate_bps;
  }

  virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
                                       unsigned int bitrate) OVERRIDE {
    CriticalSectionScoped lock(critical_section_.get());
    assert(expected_bitrate_bps_ > 0);
    if (bitrate >= expected_bitrate_bps_) {
      // Just trigger if there was any rtx padding packet.
      if (rtx_media_ssrcs_.empty() || rtx_media_sent_ > 0) {
        TriggerTestDone();
      }
    }
    rtp_rtcp_->SetREMBData(
        bitrate, static_cast<uint8_t>(ssrcs.size()), &ssrcs[0]);
    rtp_rtcp_->Process();
  }

  virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE {
    CriticalSectionScoped lock(critical_section_.get());
    RTPHeader header;
    EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
    receive_stats_->IncomingPacket(header, length, false);
    payload_registry_->SetIncomingPayloadType(header);
    remote_bitrate_estimator_->IncomingPacket(
        clock_->TimeInMilliseconds(), static_cast<int>(length - 12), header);
    if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
      remote_bitrate_estimator_->Process();
    }
    total_sent_ += length;
    padding_sent_ += header.paddingLength;
    ++total_packets_sent_;
    if (header.paddingLength > 0)
      ++padding_packets_sent_;
    if (rtx_media_ssrcs_.find(header.ssrc) != rtx_media_ssrcs_.end()) {
      rtx_media_sent_ += length - header.headerLength - header.paddingLength;
      if (header.paddingLength == 0)
        ++rtx_media_packets_sent_;
      uint8_t restored_packet[kMaxPacketSize];
      uint8_t* restored_packet_ptr = restored_packet;
      int restored_length = static_cast<int>(length);
      payload_registry_->RestoreOriginalPacket(&restored_packet_ptr,
                                               packet,
                                               &restored_length,
                                               rtx_media_ssrcs_[header.ssrc],
                                               header);
      length = restored_length;
      EXPECT_TRUE(rtp_parser_->Parse(
          restored_packet, static_cast<int>(length), &header));
    } else {
      rtp_rtcp_->SetRemoteSSRC(header.ssrc);
    }
    return true;
  }

  virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    return true;
  }

  EventTypeWrapper Wait() { return test_done_->Wait(120 * 1000); }

 private:
  void ReportResult(const std::string& measurement,
                    size_t value,
                    const std::string& units) {
    webrtc::test::PrintResult(
        measurement, "",
        ::testing::UnitTest::GetInstance()->current_test_info()->name(),
        value, units, false);
  }

  void TriggerTestDone() {
    ReportResult("total-sent", total_sent_, "bytes");
    ReportResult("padding-sent", padding_sent_, "bytes");
    ReportResult("rtx-media-sent", rtx_media_sent_, "bytes");
    ReportResult("total-packets-sent", total_packets_sent_, "packets");
    ReportResult("padding-packets-sent", padding_packets_sent_, "packets");
    ReportResult("rtx-packets-sent", rtx_media_packets_sent_, "packets");
    test_done_->Set();
  }

  scoped_ptr<CriticalSectionWrapper> critical_section_;
  scoped_ptr<EventWrapper> test_done_;
  scoped_ptr<RtpHeaderParser> rtp_parser_;
  scoped_ptr<RtpRtcp> rtp_rtcp_;
  internal::TransportAdapter feedback_transport_;
  scoped_ptr<ReceiveStatistics> receive_stats_;
  scoped_ptr<RTPPayloadRegistry> payload_registry_;
  scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
  Clock* clock_;
  unsigned int expected_bitrate_bps_;
  SsrcMap rtx_media_ssrcs_;
  size_t total_sent_;
  size_t padding_sent_;
  size_t rtx_media_sent_;
  int total_packets_sent_;
  int padding_packets_sent_;
  int rtx_media_packets_sent_;
};

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)
      : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
        test_done_(EventWrapper::Create()),
        rtp_parser_(RtpHeaderParser::Create()),
        feedback_transport_(feedback_transport),
        receive_stats_(ReceiveStatistics::Create(clock)),
        clock_(clock),
        test_state_(kFirstRampup),
        state_start_ms_(clock_->TimeInMilliseconds()),
        interval_start_ms_(state_start_ms_),
        last_remb_bps_(0),
        sent_bytes_(0),
        total_overuse_bytes_(0),
        number_of_streams_(number_of_streams),
        rtx_used_(rtx_used),
        send_stream_(NULL),
        suspended_in_stats_(false) {
    RtpRtcp::Configuration config;
    config.receive_statistics = receive_stats_.get();
    feedback_transport_.Enable();
    config.outgoing_transport = &feedback_transport_;
    rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
    rtp_rtcp_->SetREMBStatus(true);
    rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
    rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
                                            kAbsoluteSendTimeExtensionId);
    AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory;
    const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 10000;
    remote_bitrate_estimator_.reset(
        rbe_factory.Create(this, clock, kMimdControl,
                           kRemoteBitrateEstimatorMinBitrateBps));
    forward_transport_config_.link_capacity_kbps =
        kHighBandwidthLimitBps / 1000;
    forward_transport_config_.queue_length = 100;  // Something large.
    test::DirectTransport::SetConfig(forward_transport_config_);
    test::DirectTransport::SetReceiver(this);
  }

  virtual void SetSendStream(const VideoSendStream* send_stream) {
    send_stream_ = send_stream;
  }

  virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
                                       unsigned int bitrate) {
    CriticalSectionScoped lock(critical_section_.get());
    rtp_rtcp_->SetREMBData(
        bitrate, static_cast<uint8_t>(ssrcs.size()), &ssrcs[0]);
    rtp_rtcp_->Process();
    last_remb_bps_ = bitrate;
  }

  virtual bool SendRtp(const uint8_t* data, size_t length) OVERRIDE {
    sent_bytes_ += length;
    int64_t now_ms = clock_->TimeInMilliseconds();
    if (now_ms > interval_start_ms_ + 1000) {  // Let at least 1 second pass.
      // Verify that the send rate was about right.
      unsigned int average_rate_bps = static_cast<unsigned int>(sent_bytes_) *
                                      8 * 1000 / (now_ms - interval_start_ms_);
      // TODO(holmer): Why is this failing?
      // EXPECT_LT(average_rate_bps, last_remb_bps_ * 1.1);
      if (average_rate_bps > last_remb_bps_ * 1.1) {
        total_overuse_bytes_ +=
            sent_bytes_ -
            last_remb_bps_ / 8 * (now_ms - interval_start_ms_) / 1000;
      }
      EvolveTestState(average_rate_bps);
      interval_start_ms_ = now_ms;
      sent_bytes_ = 0;
    }
    return test::DirectTransport::SendRtp(data, length);
  }

  virtual bool DeliverPacket(const uint8_t* packet, size_t length) OVERRIDE {
    CriticalSectionScoped lock(critical_section_.get());
    RTPHeader header;
    EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
    receive_stats_->IncomingPacket(header, length, false);
    remote_bitrate_estimator_->IncomingPacket(
        clock_->TimeInMilliseconds(), static_cast<int>(length - 12), header);
    if (remote_bitrate_estimator_->TimeUntilNextProcess() <= 0) {
      remote_bitrate_estimator_->Process();
    }
    suspended_in_stats_ = send_stream_->GetStats().suspended;
    return true;
  }

  virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    return true;
  }

  // Produces a string similar to "1stream_nortx", depending on the values of
  // number_of_streams_ and rtx_used_;
  std::string GetModifierString() {
    std::string str("_");
    char temp_str[5];
    sprintf(temp_str, "%i", static_cast<int>(number_of_streams_));
    str += std::string(temp_str);
    str += "stream";
    str += (number_of_streams_ > 1 ? "s" : "");
    str += "_";
    str += (rtx_used_ ? "" : "no");
    str += "rtx";
    return str;
  }

  // This method defines the state machine for the ramp up-down-up test.
  void EvolveTestState(unsigned int bitrate_bps) {
    int64_t now = clock_->TimeInMilliseconds();
    assert(send_stream_ != NULL);
    CriticalSectionScoped lock(critical_section_.get());
    switch (test_state_) {
      case kFirstRampup: {
        EXPECT_FALSE(suspended_in_stats_);
        if (bitrate_bps > kExpectedHighBitrateBps) {
          // The first ramp-up has reached the target bitrate. Change the
          // channel limit, and move to the next test state.
          forward_transport_config_.link_capacity_kbps =
              kLowBandwidthLimitBps / 1000;
          test::DirectTransport::SetConfig(forward_transport_config_);
          test_state_ = kLowRate;
          webrtc::test::PrintResult("ramp_up_down_up",
                                    GetModifierString(),
                                    "first_rampup",
                                    now - state_start_ms_,
                                    "ms",
                                    false);
          state_start_ms_ = now;
          interval_start_ms_ = now;
          sent_bytes_ = 0;
        }
        break;
      }
      case kLowRate: {
        if (bitrate_bps < kExpectedLowBitrateBps && suspended_in_stats_) {
          // The ramp-down was successful. Change the channel limit back to a
          // high value, and move to the next test state.
          forward_transport_config_.link_capacity_kbps =
              kHighBandwidthLimitBps / 1000;
          test::DirectTransport::SetConfig(forward_transport_config_);
          test_state_ = kSecondRampup;
          webrtc::test::PrintResult("ramp_up_down_up",
                                    GetModifierString(),
                                    "rampdown",
                                    now - state_start_ms_,
                                    "ms",
                                    false);
          state_start_ms_ = now;
          interval_start_ms_ = now;
          sent_bytes_ = 0;
        }
        break;
      }
      case kSecondRampup: {
        if (bitrate_bps > kExpectedHighBitrateBps && !suspended_in_stats_) {
          webrtc::test::PrintResult("ramp_up_down_up",
                                    GetModifierString(),
                                    "second_rampup",
                                    now - state_start_ms_,
                                    "ms",
                                    false);
          webrtc::test::PrintResult("ramp_up_down_up",
                                    GetModifierString(),
                                    "total_overuse",
                                    total_overuse_bytes_,
                                    "bytes",
                                    false);
          test_done_->Set();
        }
        break;
      }
    }
  }

  EventTypeWrapper Wait() { return test_done_->Wait(120 * 1000); }

 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 };

  scoped_ptr<CriticalSectionWrapper> critical_section_;
  scoped_ptr<EventWrapper> test_done_;
  scoped_ptr<RtpHeaderParser> rtp_parser_;
  scoped_ptr<RtpRtcp> rtp_rtcp_;
  internal::TransportAdapter feedback_transport_;
  scoped_ptr<ReceiveStatistics> receive_stats_;
  scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
  Clock* clock_;
  FakeNetworkPipe::Config forward_transport_config_;
  TestStates test_state_;
  int64_t state_start_ms_;
  int64_t interval_start_ms_;
  unsigned int last_remb_bps_;
  size_t sent_bytes_;
  size_t total_overuse_bytes_;
  const size_t number_of_streams_;
  const bool rtx_used_;
  const VideoSendStream* send_stream_;
  bool suspended_in_stats_ GUARDED_BY(critical_section_);
};
}

class RampUpTest : public ::testing::Test {
 public:
  virtual void SetUp() { reserved_ssrcs_.clear(); }

 protected:
  void RunRampUpTest(bool pacing, bool rtx, size_t num_streams) {
    std::vector<uint32_t> ssrcs(GenerateSsrcs(num_streams, 100));
    std::vector<uint32_t> rtx_ssrcs(GenerateSsrcs(num_streams, 200));
    StreamObserver::SsrcMap rtx_ssrc_map;
    if (rtx) {
      for (size_t i = 0; i < ssrcs.size(); ++i)
        rtx_ssrc_map[rtx_ssrcs[i]] = ssrcs[i];
    }
    test::DirectTransport receiver_transport;
    StreamObserver stream_observer(rtx_ssrc_map,
                                   &receiver_transport,
                                   Clock::GetRealTimeClock());

    Call::Config call_config(&stream_observer);
    webrtc::Config webrtc_config;
    call_config.webrtc_config = &webrtc_config;
    webrtc_config.Set<PaddingStrategy>(new PaddingStrategy(rtx));
    scoped_ptr<Call> call(Call::Create(call_config));
    VideoSendStream::Config send_config = call->GetDefaultSendConfig();

    receiver_transport.SetReceiver(call->Receiver());

    test::FakeEncoder encoder(Clock::GetRealTimeClock());
    send_config.encoder_settings =
        test::CreateEncoderSettings(&encoder, "FAKE", 125, num_streams);

    if (num_streams == 1) {
      send_config.encoder_settings.streams[0].target_bitrate_bps = 2000000;
      send_config.encoder_settings.streams[0].max_bitrate_bps = 2000000;
    }

    send_config.pacing = pacing;
    send_config.rtp.nack.rtp_history_ms = 1000;
    send_config.rtp.ssrcs = ssrcs;
    if (rtx) {
      send_config.rtp.rtx.payload_type = 96;
      send_config.rtp.rtx.ssrcs = rtx_ssrcs;
    }
    send_config.rtp.extensions.push_back(
        RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId));

    if (num_streams == 1) {
      // For single stream rampup until 1mbps
      stream_observer.set_expected_bitrate_bps(1000000);
    } else {
      // For multi stream rampup until all streams are being sent. That means
      // enough birate to sent all the target streams plus the min bitrate of
      // the last one.
      int expected_bitrate_bps =
          send_config.encoder_settings.streams.back().min_bitrate_bps;
      for (size_t i = 0; i < send_config.encoder_settings.streams.size() - 1;
           ++i) {
        expected_bitrate_bps +=
            send_config.encoder_settings.streams[i].target_bitrate_bps;
      }
      stream_observer.set_expected_bitrate_bps(expected_bitrate_bps);
    }

    VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);

    scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
        test::FrameGeneratorCapturer::Create(
            send_stream->Input(),
            send_config.encoder_settings.streams.back().width,
            send_config.encoder_settings.streams.back().height,
            send_config.encoder_settings.streams.back().max_framerate,
            Clock::GetRealTimeClock()));

    send_stream->StartSending();
    frame_generator_capturer->Start();

    EXPECT_EQ(kEventSignaled, stream_observer.Wait());

    frame_generator_capturer->Stop();
    send_stream->StopSending();

    call->DestroyVideoSendStream(send_stream);
  }

  void RunRampUpDownUpTest(size_t number_of_streams, bool rtx) {
    std::vector<uint32_t> ssrcs;
    for (size_t i = 0; i < number_of_streams; ++i)
      ssrcs.push_back(static_cast<uint32_t>(i + 1));
    test::DirectTransport receiver_transport;
    LowRateStreamObserver stream_observer(
        &receiver_transport, Clock::GetRealTimeClock(), number_of_streams, rtx);

    Call::Config call_config(&stream_observer);
    webrtc::Config webrtc_config;
    call_config.webrtc_config = &webrtc_config;
    webrtc_config.Set<PaddingStrategy>(new PaddingStrategy(rtx));
    scoped_ptr<Call> call(Call::Create(call_config));
    VideoSendStream::Config send_config = call->GetDefaultSendConfig();

    receiver_transport.SetReceiver(call->Receiver());

    test::FakeEncoder encoder(Clock::GetRealTimeClock());
    send_config.encoder_settings =
        test::CreateEncoderSettings(&encoder, "FAKE", 125, number_of_streams);
    send_config.rtp.nack.rtp_history_ms = 1000;
    send_config.rtp.ssrcs.insert(
        send_config.rtp.ssrcs.begin(), ssrcs.begin(), ssrcs.end());
    send_config.rtp.extensions.push_back(
        RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId));
    send_config.suspend_below_min_bitrate = true;

    VideoSendStream* send_stream = call->CreateVideoSendStream(send_config);
    stream_observer.SetSendStream(send_stream);

    size_t width = 0;
    size_t height = 0;
    for (size_t i = 0; i < send_config.encoder_settings.streams.size(); ++i) {
      size_t stream_width = send_config.encoder_settings.streams[i].width;
      size_t stream_height = send_config.encoder_settings.streams[i].height;
      if (stream_width > width)
        width = stream_width;
      if (stream_height > height)
        height = stream_height;
    }

    scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
        test::FrameGeneratorCapturer::Create(send_stream->Input(),
                                             width,
                                             height,
                                             30,
                                             Clock::GetRealTimeClock()));

    send_stream->StartSending();
    frame_generator_capturer->Start();

    EXPECT_EQ(kEventSignaled, stream_observer.Wait());

    stream_observer.StopSending();
    receiver_transport.StopSending();
    frame_generator_capturer->Stop();
    send_stream->StopSending();

    call->DestroyVideoSendStream(send_stream);
  }

 private:
  std::vector<uint32_t> GenerateSsrcs(size_t num_streams,
                                      uint32_t ssrc_offset) {
    std::vector<uint32_t> ssrcs;
    for (size_t i = 0; i != num_streams; ++i)
      ssrcs.push_back(static_cast<uint32_t>(ssrc_offset + i));
    return ssrcs;
  }

  std::map<uint32_t, bool> reserved_ssrcs_;
};

TEST_F(RampUpTest, SingleStreamWithoutPacing) {
  RunRampUpTest(false, false, 1);
}

TEST_F(RampUpTest, SingleStreamWithPacing) {
  RunRampUpTest(true, false, 1);
}

TEST_F(RampUpTest, SimulcastWithoutPacing) {
  RunRampUpTest(false, false, 3);
}

TEST_F(RampUpTest, SimulcastWithPacing) {
  RunRampUpTest(true, false, 3);
}

// TODO(pbos): Re-enable, webrtc:2992.
TEST_F(RampUpTest, DISABLED_SimulcastWithPacingAndRtx) {
  RunRampUpTest(true, true, 3);
}

TEST_F(RampUpTest, UpDownUpOneStream) { RunRampUpDownUpTest(1, false); }

TEST_F(RampUpTest, UpDownUpThreeStreams) { RunRampUpDownUpTest(3, false); }

TEST_F(RampUpTest, UpDownUpOneStreamRtx) { RunRampUpDownUpTest(1, true); }

TEST_F(RampUpTest, UpDownUpThreeStreamsRtx) { RunRampUpDownUpTest(3, true); }

}  // namespace webrtc
