/*
 *  Copyright (c) 2015 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 <list>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/video_engine/payload_router.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::NiceMock;
using ::testing::Return;

namespace webrtc {

class PayloadRouterTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    payload_router_.reset(new PayloadRouter());
  }
  rtc::scoped_ptr<PayloadRouter> payload_router_;
};

TEST_F(PayloadRouterTest, SendOnOneModule) {
  MockRtpRtcp rtp;
  std::list<RtpRtcp*> modules(1, &rtp);

  payload_router_->SetSendingRtpModules(modules);

  uint8_t payload = 'a';
  FrameType frame_type = kVideoFrameKey;
  int8_t payload_type = 96;

  EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
                                    NULL))
      .Times(0);
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
                                             &payload, 1, NULL, NULL));

  payload_router_->set_active(true);
  EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
                                    NULL))
      .Times(1);
  EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
                                            &payload, 1, NULL, NULL));

  payload_router_->set_active(false);
  EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
                                    NULL))
      .Times(0);
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
                                             &payload, 1, NULL, NULL));

  payload_router_->set_active(true);
  EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
                                    NULL))
      .Times(1);
  EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
                                            &payload, 1, NULL, NULL));

  modules.clear();
  payload_router_->SetSendingRtpModules(modules);
  EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1, NULL,
                                    NULL))
      .Times(0);
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
                                             &payload, 1, NULL, NULL));
}

TEST_F(PayloadRouterTest, SendSimulcast) {
  MockRtpRtcp rtp_1;
  MockRtpRtcp rtp_2;
  std::list<RtpRtcp*> modules;
  modules.push_back(&rtp_1);
  modules.push_back(&rtp_2);

  payload_router_->SetSendingRtpModules(modules);

  uint8_t payload_1 = 'a';
  FrameType frame_type_1 = kVideoFrameKey;
  int8_t payload_type_1 = 96;
  RTPVideoHeader rtp_hdr_1;
  rtp_hdr_1.simulcastIdx = 0;

  payload_router_->set_active(true);
  EXPECT_CALL(rtp_1, SendOutgoingData(frame_type_1, payload_type_1, 0, 0, _, 1,
                                      NULL, &rtp_hdr_1))
      .Times(1);
  EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_TRUE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
                                            &payload_1, 1, NULL, &rtp_hdr_1));

  uint8_t payload_2 = 'b';
  FrameType frame_type_2 = kVideoFrameDelta;
  int8_t payload_type_2 = 97;
  RTPVideoHeader rtp_hdr_2;
  rtp_hdr_2.simulcastIdx = 1;
  EXPECT_CALL(rtp_2, SendOutgoingData(frame_type_2, payload_type_2, 0, 0, _, 1,
                                      NULL, &rtp_hdr_2))
      .Times(1);
  EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_TRUE(payload_router_->RoutePayload(frame_type_2, payload_type_2, 0, 0,
                                            &payload_2, 1, NULL, &rtp_hdr_2));

  // Inactive.
  payload_router_->set_active(false);
  EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
                                             &payload_1, 1, NULL, &rtp_hdr_1));
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type_2, payload_type_2, 0, 0,
                                             &payload_2, 1, NULL, &rtp_hdr_2));

  // Invalid simulcast index.
  payload_router_->set_active(true);
  EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
      .Times(0);
  rtp_hdr_1.simulcastIdx = 2;
  EXPECT_FALSE(payload_router_->RoutePayload(frame_type_1, payload_type_1, 0, 0,
                                             &payload_1, 1, NULL, &rtp_hdr_1));
}

TEST_F(PayloadRouterTest, MaxPayloadLength) {
  // Without any limitations from the modules, verify we get the max payload
  // length for IP/UDP/SRTP with a MTU of 150 bytes.
  const size_t kDefaultMaxLength = 1500 - 20 - 8 - 12 - 4;
  EXPECT_EQ(kDefaultMaxLength, payload_router_->DefaultMaxPayloadLength());
  EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());

  MockRtpRtcp rtp_1;
  MockRtpRtcp rtp_2;
  std::list<RtpRtcp*> modules;
  modules.push_back(&rtp_1);
  modules.push_back(&rtp_2);
  payload_router_->SetSendingRtpModules(modules);

  // Modules return a higher length than the default value.
  EXPECT_CALL(rtp_1, MaxDataPayloadLength())
      .Times(1)
      .WillOnce(Return(kDefaultMaxLength + 10));
  EXPECT_CALL(rtp_2, MaxDataPayloadLength())
      .Times(1)
      .WillOnce(Return(kDefaultMaxLength + 10));
  EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());

  // The modules return a value lower than default.
  const size_t kTestMinPayloadLength = 1001;
  EXPECT_CALL(rtp_1, MaxDataPayloadLength())
      .Times(1)
      .WillOnce(Return(kTestMinPayloadLength + 10));
  EXPECT_CALL(rtp_2, MaxDataPayloadLength())
      .Times(1)
      .WillOnce(Return(kTestMinPayloadLength));
  EXPECT_EQ(kTestMinPayloadLength, payload_router_->MaxPayloadLength());
}

TEST_F(PayloadRouterTest, SetTargetSendBitrates) {
  MockRtpRtcp rtp_1;
  MockRtpRtcp rtp_2;
  std::list<RtpRtcp*> modules;
  modules.push_back(&rtp_1);
  modules.push_back(&rtp_2);
  payload_router_->SetSendingRtpModules(modules);

  const uint32_t bitrate_1 = 10000;
  const uint32_t bitrate_2 = 76543;
  std::vector<uint32_t> bitrates (2, bitrate_1);
  bitrates[1] = bitrate_2;
  EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
      .Times(1);
  EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
      .Times(1);
  payload_router_->SetTargetSendBitrates(bitrates);

  bitrates.resize(1);
  EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
      .Times(0);
  EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
      .Times(0);
  payload_router_->SetTargetSendBitrates(bitrates);

  bitrates.resize(3);
  bitrates[1] = bitrate_2;
  bitrates[2] = bitrate_1 + bitrate_2;
  EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
      .Times(1);
  EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
      .Times(1);
  payload_router_->SetTargetSendBitrates(bitrates);
}
}  // namespace webrtc
