/*
 *  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.
 */

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

#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/test/null_transport.h"
#include "webrtc/typedefs.h"

namespace {

using namespace webrtc;


class TestTransport : public Transport {
 public:
  TestTransport(RTCPReceiver* rtcp_receiver) :
    rtcp_receiver_(rtcp_receiver) {
  }

  bool SendRtp(const uint8_t* /*data*/,
               size_t /*len*/,
               const PacketOptions& options) override {
    return false;
  }
  bool SendRtcp(const uint8_t* packet, size_t packetLength) override {
    RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet,
                                         packetLength,
                                         true); // Allow non-compound RTCP

    EXPECT_TRUE(rtcpParser.IsValid());
    RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
    EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation,
                                                    &rtcpParser));

    EXPECT_EQ((uint32_t)kRtcpRemb,
              rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb);
    EXPECT_EQ((uint32_t)1234,
              rtcpPacketInformation.receiverEstimatedMaxBitrate);
    return true;
  }
 private:
  RTCPReceiver* rtcp_receiver_;
};


class RtcpFormatRembTest : public ::testing::Test {
 protected:
  RtcpFormatRembTest()
      : system_clock_(Clock::GetRealTimeClock()),
        dummy_rtp_rtcp_impl_(nullptr),
        receive_statistics_(ReceiveStatistics::Create(system_clock_)),
        rtcp_sender_(nullptr),
        rtcp_receiver_(nullptr),
        test_transport_(nullptr),
        remote_bitrate_observer_(),
        remote_bitrate_estimator_(
            new RemoteBitrateEstimatorSingleStream(&remote_bitrate_observer_,
                                                   system_clock_)) {}
  void SetUp() override;
  void TearDown() override;

  Clock* system_clock_;
  ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_;
  rtc::scoped_ptr<ReceiveStatistics> receive_statistics_;
  RTCPSender* rtcp_sender_;
  RTCPReceiver* rtcp_receiver_;
  TestTransport* test_transport_;
  test::NullTransport null_transport_;
  MockRemoteBitrateObserver remote_bitrate_observer_;
  rtc::scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
};

void RtcpFormatRembTest::SetUp() {
  RtpRtcp::Configuration configuration;
  configuration.audio = false;
  configuration.clock = system_clock_;
  configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
  configuration.outgoing_transport = &null_transport_;
  dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
  rtcp_receiver_ = new RTCPReceiver(system_clock_, false, nullptr, nullptr,
                                    nullptr, nullptr, dummy_rtp_rtcp_impl_);
  test_transport_ = new TestTransport(rtcp_receiver_);
  rtcp_sender_ = new RTCPSender(false, system_clock_, receive_statistics_.get(),
                                nullptr, test_transport_);
}

void RtcpFormatRembTest::TearDown() {
  delete rtcp_sender_;
  delete rtcp_receiver_;
  delete dummy_rtp_rtcp_impl_;
  delete test_transport_;
}

TEST_F(RtcpFormatRembTest, TestRembStatus) {
  EXPECT_FALSE(rtcp_sender_->REMB());
  rtcp_sender_->SetREMBStatus(true);
  EXPECT_TRUE(rtcp_sender_->REMB());
  rtcp_sender_->SetREMBStatus(false);
  EXPECT_FALSE(rtcp_sender_->REMB());
}

TEST_F(RtcpFormatRembTest, TestNonCompund) {
  uint32_t SSRC = 456789;
  rtcp_sender_->SetRTCPStatus(RtcpMode::kReducedSize);
  rtcp_sender_->SetREMBData(1234, std::vector<uint32_t>(1, SSRC));
  RTCPSender::FeedbackState feedback_state =
      dummy_rtp_rtcp_impl_->GetFeedbackState();
  EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRemb));
}

TEST_F(RtcpFormatRembTest, TestCompund) {
  uint32_t SSRCs[2] = {456789, 98765};
  rtcp_sender_->SetRTCPStatus(RtcpMode::kCompound);
  rtcp_sender_->SetREMBData(1234, std::vector<uint32_t>(SSRCs, SSRCs + 2));
  RTCPSender::FeedbackState feedback_state =
      dummy_rtp_rtcp_impl_->GetFeedbackState();
  EXPECT_EQ(0, rtcp_sender_->SendRTCP(feedback_state, kRtcpRemb));
}
}  // namespace
