/*
 *  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 <algorithm>
#include <vector>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"

using namespace webrtc;

const uint64_t kTestPictureId = 12345678;
const uint8_t kSliPictureId = 156;

class RtcpCallback : public RtcpIntraFrameObserver {
 public:
  void SetModule(RtpRtcp* module) {
    _rtpRtcpModule = module;
  };
  virtual void OnRTCPPacketTimeout(const int32_t id) {
  }
  virtual void OnLipSyncUpdate(const int32_t id,
                               const int32_t audioVideoOffset) {
  };
  virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {
  };
  virtual void OnReceivedSLI(uint32_t ssrc,
                             uint8_t pictureId) {
    EXPECT_EQ(kSliPictureId & 0x3f, pictureId);
  };
  virtual void OnReceivedRPSI(uint32_t ssrc,
                              uint64_t pictureId) {
    EXPECT_EQ(kTestPictureId, pictureId);
  };
  virtual void OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) {};
 private:
  RtpRtcp* _rtpRtcpModule;
};

class TestRtpFeedback : public NullRtpFeedback {
 public:
  TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
  virtual ~TestRtpFeedback() {}

  void OnIncomingSSRCChanged(const uint32_t ssrc) override {
    rtp_rtcp_->SetRemoteSSRC(ssrc);
  }

 private:
  RtpRtcp* rtp_rtcp_;
};

class RtpRtcpRtcpTest : public ::testing::Test {
 protected:
  RtpRtcpRtcpTest() : fake_clock(123456) {
    test_csrcs.push_back(1234);
    test_csrcs.push_back(2345);
    test_ssrc = 3456;
    test_timestamp = 4567;
    test_sequence_number = 2345;
  }
  ~RtpRtcpRtcpTest() {}

  virtual void SetUp() {
    receiver = new TestRtpReceiver();
    transport1 = new LoopBackTransport();
    transport2 = new LoopBackTransport();
    myRTCPFeedback1 = new RtcpCallback();
    myRTCPFeedback2 = new RtcpCallback();

    receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
    receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));

    RtpRtcp::Configuration configuration;
    configuration.audio = true;
    configuration.clock = &fake_clock;
    configuration.receive_statistics = receive_statistics1_.get();
    configuration.outgoing_transport = transport1;
    configuration.intra_frame_callback = myRTCPFeedback1;

    rtp_payload_registry1_.reset(new RTPPayloadRegistry(
            RTPPayloadStrategy::CreateStrategy(true)));
    rtp_payload_registry2_.reset(new RTPPayloadRegistry(
            RTPPayloadStrategy::CreateStrategy(true)));

    module1 = RtpRtcp::CreateRtpRtcp(configuration);

    rtp_feedback1_.reset(new TestRtpFeedback(module1));

    rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
        &fake_clock, NULL, receiver, rtp_feedback1_.get(),
        rtp_payload_registry1_.get()));

    configuration.receive_statistics = receive_statistics2_.get();
    configuration.outgoing_transport = transport2;
    configuration.intra_frame_callback = myRTCPFeedback2;

    module2 = RtpRtcp::CreateRtpRtcp(configuration);

    rtp_feedback2_.reset(new TestRtpFeedback(module2));

    rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
        &fake_clock, NULL, receiver, rtp_feedback2_.get(),
        rtp_payload_registry2_.get()));

    transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
                              rtp_receiver2_.get(), receive_statistics2_.get());
    transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
                              rtp_receiver1_.get(), receive_statistics1_.get());
    myRTCPFeedback1->SetModule(module1);
    myRTCPFeedback2->SetModule(module2);

    module1->SetRTCPStatus(RtcpMode::kCompound);
    module2->SetRTCPStatus(RtcpMode::kCompound);

    module2->SetSSRC(test_ssrc + 1);
    module1->SetSSRC(test_ssrc);
    module1->SetSequenceNumber(test_sequence_number);
    module1->SetStartTimestamp(test_timestamp);

    module1->SetCsrcs(test_csrcs);
    EXPECT_EQ(0, module1->SetCNAME("john.doe@test.test"));

    EXPECT_EQ(0, module1->SetSendingStatus(true));

    CodecInst voice_codec;
    voice_codec.pltype = 96;
    voice_codec.plfreq = 8000;
    voice_codec.rate = 64000;
    memcpy(voice_codec.plname, "PCMU", 5);

    EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
    EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
        voice_codec.plname,
        voice_codec.pltype,
        voice_codec.plfreq,
        voice_codec.channels,
        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
    EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
    EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
        voice_codec.plname,
        voice_codec.pltype,
        voice_codec.plfreq,
        voice_codec.channels,
        (voice_codec.rate < 0) ? 0 : voice_codec.rate));

    // We need to send one RTP packet to get the RTCP packet to be accepted by
    // the receiving module.
    // send RTP packet with the data "testtest"
    const uint8_t test[9] = "testtest";
    EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
                                           0, -1, test, 8));
  }

  virtual void TearDown() {
    delete module1;
    delete module2;
    delete myRTCPFeedback1;
    delete myRTCPFeedback2;
    delete transport1;
    delete transport2;
    delete receiver;
  }

  rtc::scoped_ptr<TestRtpFeedback> rtp_feedback1_;
  rtc::scoped_ptr<TestRtpFeedback> rtp_feedback2_;
  rtc::scoped_ptr<ReceiveStatistics> receive_statistics1_;
  rtc::scoped_ptr<ReceiveStatistics> receive_statistics2_;
  rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
  rtc::scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
  rtc::scoped_ptr<RtpReceiver> rtp_receiver1_;
  rtc::scoped_ptr<RtpReceiver> rtp_receiver2_;
  RtpRtcp* module1;
  RtpRtcp* module2;
  TestRtpReceiver* receiver;
  LoopBackTransport* transport1;
  LoopBackTransport* transport2;
  RtcpCallback* myRTCPFeedback1;
  RtcpCallback* myRTCPFeedback2;

  uint32_t test_ssrc;
  uint32_t test_timestamp;
  uint16_t test_sequence_number;
  std::vector<uint32_t> test_csrcs;
  SimulatedClock fake_clock;
};

TEST_F(RtpRtcpRtcpTest, RTCP_PLI_RPSI) {
  EXPECT_EQ(0, module1->SendRTCPReferencePictureSelection(kTestPictureId));
  EXPECT_EQ(0, module1->SendRTCPSliceLossIndication(kSliPictureId));
}

TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
  uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
  EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
  EXPECT_EQ(test_csrcs[0], testOfCSRC[0]);
  EXPECT_EQ(test_csrcs[1], testOfCSRC[1]);

  // Set cname of mixed.
  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[0], "john@192.168.0.1"));
  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));

  EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_csrcs[0] + 1));
  EXPECT_EQ(0, module1->RemoveMixedCNAME(test_csrcs[1]));
  EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));

  // send RTCP packet, triggered by timer
  fake_clock.AdvanceTimeMilliseconds(7500);
  module1->Process();
  fake_clock.AdvanceTimeMilliseconds(100);
  module2->Process();

  char cName[RTCP_CNAME_SIZE];
  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC() + 1, cName));

  // Check multiple CNAME.
  EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
  EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));

  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[0], cName));
  EXPECT_EQ(0, strncmp(cName, "john@192.168.0.1", RTCP_CNAME_SIZE));

  EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[1], cName));
  EXPECT_EQ(0, strncmp(cName, "jane@192.168.0.2", RTCP_CNAME_SIZE));

  EXPECT_EQ(0, module1->SetSendingStatus(false));

  // Test that BYE clears the CNAME
  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
}

TEST_F(RtpRtcpRtcpTest, RemoteRTCPStatRemote) {
  std::vector<RTCPReportBlock> report_blocks;

  EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
  EXPECT_EQ(0u, report_blocks.size());

  // send RTCP packet, triggered by timer
  fake_clock.AdvanceTimeMilliseconds(7500);
  module1->Process();
  fake_clock.AdvanceTimeMilliseconds(100);
  module2->Process();

  EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
  ASSERT_EQ(1u, report_blocks.size());

  // |test_ssrc+1| is the SSRC of module2 that send the report.
  EXPECT_EQ(test_ssrc+1, report_blocks[0].remoteSSRC);
  EXPECT_EQ(test_ssrc, report_blocks[0].sourceSSRC);

  EXPECT_EQ(0u, report_blocks[0].cumulativeLost);
  EXPECT_LT(0u, report_blocks[0].delaySinceLastSR);
  EXPECT_EQ(test_sequence_number, report_blocks[0].extendedHighSeqNum);
  EXPECT_EQ(0u, report_blocks[0].fractionLost);
}
