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


// This file includes unit tests for EncoderStateFeedback.
#include "webrtc/video/encoder_state_feedback.h"

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

#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common.h"
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
#include "webrtc/modules/pacing/paced_sender.h"
#include "webrtc/modules/pacing/packet_router.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
#include "webrtc/video/payload_router.h"
#include "webrtc/video/vie_encoder.h"

using ::testing::NiceMock;

namespace webrtc {

class MockVieEncoder : public ViEEncoder {
 public:
  explicit MockVieEncoder(ProcessThread* process_thread, PacedSender* pacer)
      : ViEEncoder(1, process_thread, nullptr, nullptr, pacer, nullptr) {}
  ~MockVieEncoder() {}

  MOCK_METHOD1(OnReceivedIntraFrameRequest,
               void(uint32_t));
  MOCK_METHOD2(OnReceivedSLI,
               void(uint32_t ssrc, uint8_t picture_id));
  MOCK_METHOD2(OnReceivedRPSI,
               void(uint32_t ssrc, uint64_t picture_id));
  MOCK_METHOD2(OnLocalSsrcChanged,
               void(uint32_t old_ssrc, uint32_t new_ssrc));
};

class VieKeyRequestTest : public ::testing::Test {
 protected:
  VieKeyRequestTest()
      : pacer_(Clock::GetRealTimeClock(),
               &router_,
               BitrateController::kDefaultStartBitrateKbps,
               PacedSender::kDefaultPaceMultiplier *
                   BitrateController::kDefaultStartBitrateKbps,
               0) {}
  virtual void SetUp() {
    process_thread_.reset(new NiceMock<MockProcessThread>);
    encoder_state_feedback_.reset(new EncoderStateFeedback());
  }
  rtc::scoped_ptr<MockProcessThread> process_thread_;
  rtc::scoped_ptr<EncoderStateFeedback> encoder_state_feedback_;
  PacketRouter router_;
  PacedSender pacer_;
};

TEST_F(VieKeyRequestTest, CreateAndTriggerRequests) {
  const int ssrc = 1234;
  MockVieEncoder encoder(process_thread_.get(), &pacer_);
  encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc), &encoder);

  EXPECT_CALL(encoder, OnReceivedIntraFrameRequest(ssrc))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->
      OnReceivedIntraFrameRequest(ssrc);

  const uint8_t sli_picture_id = 3;
  EXPECT_CALL(encoder, OnReceivedSLI(ssrc, sli_picture_id))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
      ssrc, sli_picture_id);

  const uint64_t rpsi_picture_id = 9;
  EXPECT_CALL(encoder, OnReceivedRPSI(ssrc, rpsi_picture_id))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
      ssrc, rpsi_picture_id);

  encoder_state_feedback_->RemoveEncoder(&encoder);
}

// Register multiple encoders and make sure the request is relayed to correct
// ViEEncoder.
TEST_F(VieKeyRequestTest, MultipleEncoders) {
  const int ssrc_1 = 1234;
  const int ssrc_2 = 5678;
  MockVieEncoder encoder_1(process_thread_.get(), &pacer_);
  MockVieEncoder encoder_2(process_thread_.get(), &pacer_);
  encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc_1),
                                      &encoder_1);
  encoder_state_feedback_->AddEncoder(std::vector<uint32_t>(1, ssrc_2),
                                      &encoder_2);

  EXPECT_CALL(encoder_1, OnReceivedIntraFrameRequest(ssrc_1))
      .Times(1);
  EXPECT_CALL(encoder_2, OnReceivedIntraFrameRequest(ssrc_2))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->
      OnReceivedIntraFrameRequest(ssrc_1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->
      OnReceivedIntraFrameRequest(ssrc_2);

  const uint8_t sli_pid_1 = 3;
  const uint8_t sli_pid_2 = 4;
  EXPECT_CALL(encoder_1, OnReceivedSLI(ssrc_1, sli_pid_1))
      .Times(1);
  EXPECT_CALL(encoder_2, OnReceivedSLI(ssrc_2, sli_pid_2))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
      ssrc_1, sli_pid_1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedSLI(
      ssrc_2, sli_pid_2);

  const uint64_t rpsi_pid_1 = 9;
  const uint64_t rpsi_pid_2 = 10;
  EXPECT_CALL(encoder_1, OnReceivedRPSI(ssrc_1, rpsi_pid_1))
      .Times(1);
  EXPECT_CALL(encoder_2, OnReceivedRPSI(ssrc_2, rpsi_pid_2))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
      ssrc_1, rpsi_pid_1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->OnReceivedRPSI(
      ssrc_2, rpsi_pid_2);

  encoder_state_feedback_->RemoveEncoder(&encoder_1);
  EXPECT_CALL(encoder_2, OnReceivedIntraFrameRequest(ssrc_2))
      .Times(1);
  encoder_state_feedback_->GetRtcpIntraFrameObserver()->
      OnReceivedIntraFrameRequest(ssrc_2);
  encoder_state_feedback_->RemoveEncoder(&encoder_2);
}

}  // namespace webrtc
