/*
 * libjingle
 * Copyright 2004 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/media/base/fakemediaengine.h"
#include "talk/media/base/fakenetworkinterface.h"
#include "talk/media/base/fakevideocapturer.h"
#include "talk/media/base/hybridvideoengine.h"
#include "talk/media/base/mediachannel.h"
#include "talk/media/base/testutils.h"
#include "webrtc/base/gunit.h"

static const cricket::VideoCodec kGenericCodec(97, "Generic", 640, 360, 30, 0);
static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 360, 30, 0);
static const cricket::VideoCodec kCodecsVp8Only[] = { kVp8Codec };
static const cricket::VideoCodec kCodecsGenericOnly[] = { kGenericCodec };
static const cricket::VideoCodec kCodecsVp8First[] = { kVp8Codec,
                                                       kGenericCodec };
static const cricket::VideoCodec kCodecsGenericFirst[] = { kGenericCodec,
                                                           kVp8Codec };

using cricket::StreamParams;

class FakeVp8VideoEngine : public cricket::FakeVideoEngine {
 public:
  FakeVp8VideoEngine() {
    SetCodecs(MAKE_VECTOR(kCodecsVp8Only));
  }
};
class FakeGenericVideoEngine : public cricket::FakeVideoEngine {
 public:
  FakeGenericVideoEngine() {
    SetCodecs(MAKE_VECTOR(kCodecsGenericOnly));
  }

  // For testing purposes, mimic the behavior of a media engine that throws out
  // resolutions that don't match the codec list. A width or height of 0
  // trivially will never match the codec list, so this is sufficient for
  // testing the case we want (0x0).
  virtual bool FindCodec(const cricket::VideoCodec& codec) {
    if (codec.width == 0 || codec.height == 0) {
      return false;
    } else {
      return cricket::FakeVideoEngine::FindCodec(codec);
    }
  }
};
class HybridVideoEngineForTest : public cricket::HybridVideoEngine<
    FakeVp8VideoEngine, FakeGenericVideoEngine> {
 public:
  HybridVideoEngineForTest()
      :
      num_ch1_send_on_(0),
      num_ch1_send_off_(0),
      send_width_(0),
      send_height_(0) { }
  cricket::FakeVideoEngine* sub_engine1() { return &video1_; }
  cricket::FakeVideoEngine* sub_engine2() { return &video2_; }

  // From base class HybridVideoEngine.
  void OnSendChange1(cricket::VideoMediaChannel* channel1, bool send) {
    if (send) {
      ++num_ch1_send_on_;
    } else {
      ++num_ch1_send_off_;
    }
  }
  // From base class HybridVideoEngine
  void OnNewSendResolution(int width, int height) {
    send_width_ = width;
    send_height_ = height;
  }

  int num_ch1_send_on() const { return num_ch1_send_on_; }
  int num_ch1_send_off() const { return num_ch1_send_off_; }

  int send_width() const { return send_width_; }
  int send_height() const { return send_height_; }

 private:
  int num_ch1_send_on_;
  int num_ch1_send_off_;

  int send_width_;
  int send_height_;
};

class HybridVideoEngineTest : public testing::Test {
 public:
  HybridVideoEngineTest() : sub_channel1_(NULL), sub_channel2_(NULL) {
  }
  ~HybridVideoEngineTest() {
    engine_.Terminate();
  }
  bool SetupEngine() {
    bool result = engine_.Init(rtc::Thread::Current());
    if (result) {
      channel_.reset(engine_.CreateChannel(NULL));
      result = (channel_.get() != NULL);
      sub_channel1_ = engine_.sub_engine1()->GetChannel(0);
      sub_channel2_ = engine_.sub_engine2()->GetChannel(0);
    }
    return result;
  }
  bool SetupRenderAndAddStream(const StreamParams& sp) {
    if (!SetupEngine())
      return false;
    channel_->SetInterface(transport_.get());
    return channel_->SetRecvCodecs(engine_.codecs()) &&
        channel_->AddSendStream(sp) &&
        channel_->SetRender(true);
  }
  void DeliverPacket(const void* data, int len) {
    rtc::Buffer packet(data, len);
    channel_->OnPacketReceived(&packet, rtc::CreatePacketTime(0));
  }
  void DeliverRtcp(const void* data, int len) {
    rtc::Buffer packet(data, len);
    channel_->OnRtcpReceived(&packet, rtc::CreatePacketTime(0));
  }

 protected:
  void TestSetSendCodecs(cricket::FakeVideoEngine* sub_engine,
                         const std::vector<cricket::VideoCodec>& codecs) {
    EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
    EXPECT_TRUE(channel_->SetSendCodecs(codecs));
    cricket::FakeVideoMediaChannel* sub_channel = sub_engine->GetChannel(0);
    ASSERT_EQ(1U, sub_channel->send_codecs().size());
    EXPECT_EQ(codecs[0], sub_channel->send_codecs()[0]);
    EXPECT_TRUE(channel_->SetSend(true));
    EXPECT_TRUE(sub_channel->sending());
  }
  void TestSetSendBandwidth(cricket::FakeVideoEngine* sub_engine,
                            const std::vector<cricket::VideoCodec>& codecs,
                            int start_bitrate,
                            int max_bitrate) {
    EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
    EXPECT_TRUE(channel_->SetSendCodecs(codecs));
    EXPECT_TRUE(channel_->SetStartSendBandwidth(start_bitrate));
    EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bitrate));
    cricket::FakeVideoMediaChannel* sub_channel = sub_engine->GetChannel(0);
    EXPECT_EQ(start_bitrate, sub_channel->start_bps());
    EXPECT_EQ(max_bitrate, sub_channel->max_bps());
  }
  HybridVideoEngineForTest engine_;
  rtc::scoped_ptr<cricket::HybridVideoMediaChannel> channel_;
  rtc::scoped_ptr<cricket::FakeNetworkInterface> transport_;
  cricket::FakeVideoMediaChannel* sub_channel1_;
  cricket::FakeVideoMediaChannel* sub_channel2_;
};

TEST_F(HybridVideoEngineTest, StartupShutdown) {
  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
  engine_.Terminate();
}

// Tests that SetDefaultVideoEncoderConfig passes down to both engines.
TEST_F(HybridVideoEngineTest, SetDefaultVideoEncoderConfig) {
  cricket::VideoEncoderConfig config(
      cricket::VideoCodec(105, "", 640, 400, 30, 0), 1, 2);
  EXPECT_TRUE(engine_.SetDefaultEncoderConfig(config));

  cricket::VideoEncoderConfig config_1 = config;
  config_1.max_codec.name = kCodecsVp8Only[0].name;
  EXPECT_EQ(config_1, engine_.sub_engine1()->default_encoder_config());

  cricket::VideoEncoderConfig config_2 = config;
  config_2.max_codec.name = kCodecsGenericOnly[0].name;
  EXPECT_EQ(config_2, engine_.sub_engine2()->default_encoder_config());
}

// Tests that GetDefaultVideoEncoderConfig picks a meaningful encoder config
// based on the underlying engine config and then after a call to
// SetDefaultEncoderConfig on the hybrid engine.
TEST_F(HybridVideoEngineTest, SetDefaultVideoEncoderConfigDefaultValue) {
  cricket::VideoEncoderConfig blank_config;
  cricket::VideoEncoderConfig meaningful_config1(
      cricket::VideoCodec(111, "abcd", 320, 240, 30, 0), 1, 2);
  cricket::VideoEncoderConfig meaningful_config2(
      cricket::VideoCodec(111, "abcd", 1280, 720, 30, 0), 1, 2);
  cricket::VideoEncoderConfig meaningful_config3(
      cricket::VideoCodec(111, "abcd", 640, 360, 30, 0), 1, 2);
  engine_.sub_engine1()->SetDefaultEncoderConfig(blank_config);
  engine_.sub_engine2()->SetDefaultEncoderConfig(blank_config);
  EXPECT_EQ(blank_config, engine_.GetDefaultEncoderConfig());

  engine_.sub_engine2()->SetDefaultEncoderConfig(meaningful_config2);
  EXPECT_EQ(meaningful_config2, engine_.GetDefaultEncoderConfig());

  engine_.sub_engine1()->SetDefaultEncoderConfig(meaningful_config1);
  EXPECT_EQ(meaningful_config1, engine_.GetDefaultEncoderConfig());

  EXPECT_TRUE(engine_.SetDefaultEncoderConfig(meaningful_config3));
  // The overall config should now match, though the codec name will have been
  // rewritten for the first media engine.
  meaningful_config3.max_codec.name = kCodecsVp8Only[0].name;
  EXPECT_EQ(meaningful_config3, engine_.GetDefaultEncoderConfig());
}

// Tests that our engine has the right codecs in the right order.
TEST_F(HybridVideoEngineTest, CheckCodecs) {
  const std::vector<cricket::VideoCodec>& c = engine_.codecs();
  ASSERT_EQ(2U, c.size());
  EXPECT_EQ(kVp8Codec, c[0]);
  EXPECT_EQ(kGenericCodec, c[1]);
}

// Tests that our engine has the right caps.
TEST_F(HybridVideoEngineTest, CheckCaps) {
  EXPECT_EQ(cricket::VIDEO_SEND | cricket::VIDEO_RECV,
      engine_.GetCapabilities());
}

// Tests that we can create and destroy a channel.
TEST_F(HybridVideoEngineTest, CreateChannel) {
  EXPECT_TRUE(SetupEngine());
  EXPECT_TRUE(sub_channel1_ != NULL);
  EXPECT_TRUE(sub_channel2_ != NULL);
}

// Tests that we properly handle failures in CreateChannel.
TEST_F(HybridVideoEngineTest, CreateChannelFail) {
  engine_.sub_engine1()->set_fail_create_channel(true);
  EXPECT_FALSE(SetupEngine());
  EXPECT_TRUE(channel_.get() == NULL);
  EXPECT_TRUE(sub_channel1_ == NULL);
  EXPECT_TRUE(sub_channel2_ == NULL);
  engine_.sub_engine1()->set_fail_create_channel(false);
  engine_.sub_engine2()->set_fail_create_channel(true);
  EXPECT_FALSE(SetupEngine());
  EXPECT_TRUE(channel_.get() == NULL);
  EXPECT_TRUE(sub_channel1_ == NULL);
  EXPECT_TRUE(sub_channel2_ == NULL);
}

// Test that we set our inbound codecs and settings properly.
TEST_F(HybridVideoEngineTest, SetLocalDescription) {
  EXPECT_TRUE(SetupEngine());
  channel_->SetInterface(transport_.get());
  EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
  ASSERT_EQ(1U, sub_channel1_->recv_codecs().size());
  ASSERT_EQ(1U, sub_channel2_->recv_codecs().size());
  EXPECT_EQ(kVp8Codec, sub_channel1_->recv_codecs()[0]);
  EXPECT_EQ(kGenericCodec, sub_channel2_->recv_codecs()[0]);
  StreamParams stream;
  stream.id = "TestStream";
  stream.ssrcs.push_back(1234);
  stream.cname = "5678";
  EXPECT_TRUE(channel_->AddSendStream(stream));
  EXPECT_EQ(1234U, sub_channel1_->send_ssrc());
  EXPECT_EQ(1234U, sub_channel2_->send_ssrc());
  EXPECT_EQ("5678", sub_channel1_->rtcp_cname());
  EXPECT_EQ("5678", sub_channel2_->rtcp_cname());
  EXPECT_TRUE(channel_->SetRender(true));
  // We've called SetRender, so we should be playing out, but not yet sending.
  EXPECT_TRUE(sub_channel1_->playout());
  EXPECT_TRUE(sub_channel2_->playout());
  EXPECT_FALSE(sub_channel1_->sending());
  EXPECT_FALSE(sub_channel2_->sending());
  // We may get SetSend(false) calls during call setup.
  // Since this causes no change in state, they should no-op and return true.
  EXPECT_TRUE(channel_->SetSend(false));
  EXPECT_FALSE(sub_channel1_->sending());
  EXPECT_FALSE(sub_channel2_->sending());
}

TEST_F(HybridVideoEngineTest, OnNewSendResolution) {
  EXPECT_TRUE(SetupEngine());
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
  EXPECT_EQ(640, engine_.send_width());
  EXPECT_EQ(360, engine_.send_height());
}

// Test that we converge to the active channel for engine 1.
TEST_F(HybridVideoEngineTest, SetSendCodecs1) {
  // This will nuke the object that sub_channel2_ points to.
  TestSetSendCodecs(engine_.sub_engine1(), MAKE_VECTOR(kCodecsVp8First));
  EXPECT_TRUE(engine_.sub_engine2()->GetChannel(0) == NULL);
}

// Test that we converge to the active channel for engine 2.
TEST_F(HybridVideoEngineTest, SetSendCodecs2) {
  // This will nuke the object that sub_channel1_ points to.
  TestSetSendCodecs(engine_.sub_engine2(), MAKE_VECTOR(kCodecsGenericFirst));
  EXPECT_TRUE(engine_.sub_engine1()->GetChannel(0) == NULL);
}

// Test that we don't accidentally eat 0x0 in SetSendCodecs
TEST_F(HybridVideoEngineTest, SetSendCodecs0x0) {
  EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
  // Send using generic codec, but with 0x0 resolution.
  std::vector<cricket::VideoCodec> codecs(MAKE_VECTOR(kCodecsGenericFirst));
  codecs.resize(1);
  codecs[0].width = 0;
  codecs[0].height = 0;
  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
}

// Test setting the send bandwidth for VP8.
TEST_F(HybridVideoEngineTest, SetSendBandwidth1) {
  TestSetSendBandwidth(engine_.sub_engine1(),
                       MAKE_VECTOR(kCodecsVp8First),
                       100000,
                       384000);
}

// Test setting the send bandwidth for a generic codec.
TEST_F(HybridVideoEngineTest, SetSendBandwidth2) {
  TestSetSendBandwidth(engine_.sub_engine2(),
                       MAKE_VECTOR(kCodecsGenericFirst),
                       100001,
                       384002);
}

// Test that we dump RTP packets that arrive early.
TEST_F(HybridVideoEngineTest, HandleEarlyRtp) {
  static const uint8 kPacket[1024] = { 0 };
  static const uint8 kRtcp[1024] = { 1 };
  EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
  DeliverPacket(kPacket, sizeof(kPacket));
  DeliverRtcp(kRtcp, sizeof(kRtcp));
  EXPECT_TRUE(sub_channel1_->CheckNoRtp());
  EXPECT_TRUE(sub_channel2_->CheckNoRtp());
  EXPECT_TRUE(sub_channel1_->CheckNoRtcp());
  EXPECT_TRUE(sub_channel2_->CheckNoRtcp());
}

// Test that we properly pass on normal RTP packets.
TEST_F(HybridVideoEngineTest, HandleRtp) {
  static const uint8 kPacket[1024] = { 0 };
  static const uint8 kRtcp[1024] = { 1 };
  EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
  EXPECT_TRUE(channel_->SetSend(true));
  DeliverPacket(kPacket, sizeof(kPacket));
  DeliverRtcp(kRtcp, sizeof(kRtcp));
  EXPECT_TRUE(sub_channel1_->CheckRtp(kPacket, sizeof(kPacket)));
  EXPECT_TRUE(sub_channel1_->CheckRtcp(kRtcp, sizeof(kRtcp)));
}

// Test that we properly connect media error signal.
TEST_F(HybridVideoEngineTest, MediaErrorSignal) {
  cricket::VideoMediaErrorCatcher catcher;

  // Verify no signal from either channel before the active channel is set.
  EXPECT_TRUE(SetupEngine());
  channel_->SignalMediaError.connect(&catcher,
      &cricket::VideoMediaErrorCatcher::OnError);
  sub_channel1_->SignalMediaError(1, cricket::VideoMediaChannel::ERROR_OTHER);
  EXPECT_EQ(0U, catcher.ssrc());
  sub_channel2_->SignalMediaError(2,
      cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED);
  EXPECT_EQ(0U, catcher.ssrc());

  // Set vp8 as active channel and verify that a signal comes from it.
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
  sub_channel1_->SignalMediaError(1, cricket::VideoMediaChannel::ERROR_OTHER);
  EXPECT_EQ(cricket::VideoMediaChannel::ERROR_OTHER, catcher.error());
  EXPECT_EQ(1U, catcher.ssrc());

  // Set generic codec as active channel and verify that a signal comes from it.
  EXPECT_TRUE(SetupEngine());
  channel_->SignalMediaError.connect(&catcher,
      &cricket::VideoMediaErrorCatcher::OnError);
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsGenericFirst)));
  sub_channel2_->SignalMediaError(2,
      cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED);
  EXPECT_EQ(cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED,
      catcher.error());
  EXPECT_EQ(2U, catcher.ssrc());
}

// Test that SetSend doesn't re-enter.
TEST_F(HybridVideoEngineTest, RepeatSetSend) {
  EXPECT_TRUE(SetupEngine());
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));

  // Verify initial status.
  EXPECT_FALSE(channel_->sending());
  EXPECT_FALSE(sub_channel1_->sending());
  EXPECT_EQ(0, engine_.num_ch1_send_on());
  EXPECT_EQ(0, engine_.num_ch1_send_off());

  // Verfiy SetSend(true) works correctly.
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(channel_->sending());
  EXPECT_TRUE(sub_channel1_->sending());
  EXPECT_EQ(1, engine_.num_ch1_send_on());
  EXPECT_EQ(0, engine_.num_ch1_send_off());

  // SetSend(true) again and verify nothing changes.
  EXPECT_TRUE(channel_->SetSend(true));
  EXPECT_TRUE(channel_->sending());
  EXPECT_TRUE(sub_channel1_->sending());
  EXPECT_EQ(1, engine_.num_ch1_send_on());
  EXPECT_EQ(0, engine_.num_ch1_send_off());

  // Verify SetSend(false) works correctly.
  EXPECT_TRUE(channel_->SetSend(false));
  EXPECT_FALSE(channel_->sending());
  EXPECT_FALSE(sub_channel1_->sending());
  EXPECT_EQ(1, engine_.num_ch1_send_on());
  EXPECT_EQ(1, engine_.num_ch1_send_off());

  // SetSend(false) again and verfiy nothing changes.
  EXPECT_TRUE(channel_->SetSend(false));
  EXPECT_FALSE(channel_->sending());
  EXPECT_FALSE(sub_channel1_->sending());
  EXPECT_EQ(1, engine_.num_ch1_send_on());
  EXPECT_EQ(1, engine_.num_ch1_send_off());
}

// Test that SetOptions.
TEST_F(HybridVideoEngineTest, SetOptions) {
  cricket::VideoOptions vmo;
  vmo.video_high_bitrate.Set(true);
  vmo.system_low_adaptation_threshhold.Set(0.10f);
  EXPECT_TRUE(SetupEngine());
  EXPECT_TRUE(channel_->SetOptions(vmo));

  bool high_bitrate;
  float low;
  EXPECT_TRUE(sub_channel1_->GetOptions(&vmo));
  EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
  EXPECT_TRUE(high_bitrate);
  EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
  EXPECT_EQ(0.10f, low);
  EXPECT_TRUE(sub_channel2_->GetOptions(&vmo));
  EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
  EXPECT_TRUE(high_bitrate);
  EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
  EXPECT_EQ(0.10f, low);

  vmo.video_high_bitrate.Set(false);
  vmo.system_low_adaptation_threshhold.Set(0.50f);

  EXPECT_TRUE(channel_->SetOptions(vmo));
  EXPECT_TRUE(sub_channel1_->GetOptions(&vmo));
  EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
  EXPECT_FALSE(high_bitrate);
  EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
  EXPECT_EQ(0.50f, low);
  EXPECT_TRUE(sub_channel2_->GetOptions(&vmo));
  EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
  EXPECT_FALSE(high_bitrate);
  EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
  EXPECT_EQ(0.50f, low);
}

TEST_F(HybridVideoEngineTest, SetCapturer) {
  EXPECT_TRUE(SetupEngine());
  // Set vp8 as active channel and verify that capturer can be set.
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
  cricket::FakeVideoCapturer fake_video_capturer;
  EXPECT_TRUE(channel_->SetCapturer(0, &fake_video_capturer));
  EXPECT_TRUE(channel_->SetCapturer(0, NULL));

  // Set generic codec active channel and verify that capturer can be set.
  EXPECT_TRUE(SetupEngine());
  EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsGenericFirst)));
  EXPECT_TRUE(channel_->SetCapturer(0, &fake_video_capturer));
  EXPECT_TRUE(channel_->SetCapturer(0, NULL));
}
