/*
 *  Copyright (c) 2013 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 <functional>
#include <list>
#include <memory>
#include <string>

#include "webrtc/base/checks.h"
#include "webrtc/base/event.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/call/call.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/test/call_test.h"
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/encoder_settings.h"
#include "webrtc/test/fake_decoder.h"
#include "webrtc/test/fake_encoder.h"
#include "webrtc/test/frame_generator_capturer.h"
#include "webrtc/test/gtest.h"

namespace webrtc {
namespace {
// Note: If you consider to re-use this class, think twice and instead consider
// writing tests that don't depend on the logging system.
class LogObserver {
 public:
  LogObserver() { rtc::LogMessage::AddLogToStream(&callback_, rtc::LS_INFO); }

  ~LogObserver() { rtc::LogMessage::RemoveLogToStream(&callback_); }

  void PushExpectedLogLine(const std::string& expected_log_line) {
    callback_.PushExpectedLogLine(expected_log_line);
  }

  bool Wait() { return callback_.Wait(); }

 private:
  class Callback : public rtc::LogSink {
   public:
    Callback() : done_(false, false) {}

    void OnLogMessage(const std::string& message) override {
      rtc::CritScope lock(&crit_sect_);
      // Ignore log lines that are due to missing AST extensions, these are
      // logged when we switch back from AST to TOF until the wrapping bitrate
      // estimator gives up on using AST.
      if (message.find("BitrateEstimator") != std::string::npos &&
          message.find("packet is missing") == std::string::npos) {
        received_log_lines_.push_back(message);
      }

      int num_popped = 0;
      while (!received_log_lines_.empty() && !expected_log_lines_.empty()) {
        std::string a = received_log_lines_.front();
        std::string b = expected_log_lines_.front();
        received_log_lines_.pop_front();
        expected_log_lines_.pop_front();
        num_popped++;
        EXPECT_TRUE(a.find(b) != std::string::npos) << a << " != " << b;
      }
      if (expected_log_lines_.size() <= 0) {
        if (num_popped > 0) {
          done_.Set();
        }
        return;
      }
    }

    bool Wait() { return done_.Wait(test::CallTest::kDefaultTimeoutMs); }

    void PushExpectedLogLine(const std::string& expected_log_line) {
      rtc::CritScope lock(&crit_sect_);
      expected_log_lines_.push_back(expected_log_line);
    }

   private:
    typedef std::list<std::string> Strings;
    rtc::CriticalSection crit_sect_;
    Strings received_log_lines_ GUARDED_BY(crit_sect_);
    Strings expected_log_lines_ GUARDED_BY(crit_sect_);
    rtc::Event done_;
  };

  Callback callback_;
};
}  // namespace

static const int kTOFExtensionId = 4;
static const int kASTExtensionId = 5;

class BitrateEstimatorTest : public test::CallTest {
 public:
  BitrateEstimatorTest() : receive_config_(nullptr) {}

  virtual ~BitrateEstimatorTest() { EXPECT_TRUE(streams_.empty()); }

  virtual void SetUp() {
    Call::Config config(&event_log_);
    receiver_call_.reset(Call::Create(config));
    sender_call_.reset(Call::Create(config));

    send_transport_.reset(new test::DirectTransport(sender_call_.get()));
    send_transport_->SetReceiver(receiver_call_->Receiver());
    receive_transport_.reset(new test::DirectTransport(receiver_call_.get()));
    receive_transport_->SetReceiver(sender_call_->Receiver());

    video_send_config_ = VideoSendStream::Config(send_transport_.get());
    video_send_config_.rtp.ssrcs.push_back(kVideoSendSsrcs[0]);
    // Encoders will be set separately per stream.
    video_send_config_.encoder_settings.encoder = nullptr;
    video_send_config_.encoder_settings.payload_name = "FAKE";
    video_send_config_.encoder_settings.payload_type =
        kFakeVideoSendPayloadType;
    test::FillEncoderConfiguration(1, &video_encoder_config_);

    receive_config_ = VideoReceiveStream::Config(receive_transport_.get());
    // receive_config_.decoders will be set by every stream separately.
    receive_config_.rtp.remote_ssrc = video_send_config_.rtp.ssrcs[0];
    receive_config_.rtp.local_ssrc = kReceiverLocalVideoSsrc;
    receive_config_.rtp.remb = true;
    receive_config_.rtp.extensions.push_back(
        RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
    receive_config_.rtp.extensions.push_back(
        RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
  }

  virtual void TearDown() {
    std::for_each(streams_.begin(), streams_.end(),
                  std::mem_fun(&Stream::StopSending));

    send_transport_->StopSending();
    receive_transport_->StopSending();

    while (!streams_.empty()) {
      delete streams_.back();
      streams_.pop_back();
    }

    receiver_call_.reset();
    sender_call_.reset();
  }

 protected:
  friend class Stream;

  class Stream {
   public:
    explicit Stream(BitrateEstimatorTest* test)
        : test_(test),
          is_sending_receiving_(false),
          send_stream_(nullptr),
          frame_generator_capturer_(),
          fake_encoder_(Clock::GetRealTimeClock()),
          fake_decoder_() {
      test_->video_send_config_.rtp.ssrcs[0]++;
      test_->video_send_config_.encoder_settings.encoder = &fake_encoder_;
      send_stream_ = test_->sender_call_->CreateVideoSendStream(
          test_->video_send_config_.Copy(),
          test_->video_encoder_config_.Copy());
      RTC_DCHECK_EQ(1, test_->video_encoder_config_.number_of_streams);
      frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
          kDefaultWidth, kDefaultHeight, kDefaultFramerate,
          Clock::GetRealTimeClock()));
      send_stream_->SetSource(
          frame_generator_capturer_.get(),
          VideoSendStream::DegradationPreference::kBalanced);
      send_stream_->Start();
      frame_generator_capturer_->Start();

      VideoReceiveStream::Decoder decoder;
      decoder.decoder = &fake_decoder_;
      decoder.payload_type =
          test_->video_send_config_.encoder_settings.payload_type;
      decoder.payload_name =
          test_->video_send_config_.encoder_settings.payload_name;
      test_->receive_config_.decoders.clear();
      test_->receive_config_.decoders.push_back(decoder);
      test_->receive_config_.rtp.remote_ssrc =
          test_->video_send_config_.rtp.ssrcs[0];
      test_->receive_config_.rtp.local_ssrc++;
      test_->receive_config_.renderer = &test->fake_renderer_;
      video_receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream(
          test_->receive_config_.Copy());
      video_receive_stream_->Start();
      is_sending_receiving_ = true;
    }

    ~Stream() {
      EXPECT_FALSE(is_sending_receiving_);
      test_->sender_call_->DestroyVideoSendStream(send_stream_);
      frame_generator_capturer_.reset(nullptr);
      send_stream_ = nullptr;
      if (video_receive_stream_) {
        test_->receiver_call_->DestroyVideoReceiveStream(video_receive_stream_);
        video_receive_stream_ = nullptr;
      }
    }

    void StopSending() {
      if (is_sending_receiving_) {
        frame_generator_capturer_->Stop();
        send_stream_->Stop();
        if (video_receive_stream_) {
          video_receive_stream_->Stop();
        }
        is_sending_receiving_ = false;
      }
    }

   private:
    BitrateEstimatorTest* test_;
    bool is_sending_receiving_;
    VideoSendStream* send_stream_;
    VideoReceiveStream* video_receive_stream_;
    std::unique_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
    test::FakeEncoder fake_encoder_;
    test::FakeDecoder fake_decoder_;
  };

  LogObserver receiver_log_;
  std::unique_ptr<test::DirectTransport> send_transport_;
  std::unique_ptr<test::DirectTransport> receive_transport_;
  std::unique_ptr<Call> sender_call_;
  std::unique_ptr<Call> receiver_call_;
  VideoReceiveStream::Config receive_config_;
  std::vector<Stream*> streams_;
};

static const char* kAbsSendTimeLog =
    "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
static const char* kSingleStreamLog =
    "RemoteBitrateEstimatorSingleStream: Instantiating.";

TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefaultForVideo) {
  video_send_config_.rtp.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());
}

TEST_F(BitrateEstimatorTest, ImmediatelySwitchToASTForVideo) {
  video_send_config_.rtp.extensions.push_back(
      RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId));
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
  receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());
}

TEST_F(BitrateEstimatorTest, SwitchesToASTForVideo) {
  video_send_config_.rtp.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());

  video_send_config_.rtp.extensions[0] =
      RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
  receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
  receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());
}

// This test is flaky. See webrtc:5790.
TEST_F(BitrateEstimatorTest, DISABLED_SwitchesToASTThenBackToTOFForVideo) {
  video_send_config_.rtp.extensions.push_back(
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId));
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
  receiver_log_.PushExpectedLogLine(kSingleStreamLog);
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());

  video_send_config_.rtp.extensions[0] =
      RtpExtension(RtpExtension::kAbsSendTimeUri, kASTExtensionId);
  receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
  receiver_log_.PushExpectedLogLine("Switching to absolute send time RBE.");
  streams_.push_back(new Stream(this));
  EXPECT_TRUE(receiver_log_.Wait());

  video_send_config_.rtp.extensions[0] =
      RtpExtension(RtpExtension::kTimestampOffsetUri, kTOFExtensionId);
  receiver_log_.PushExpectedLogLine(kAbsSendTimeLog);
  receiver_log_.PushExpectedLogLine(
      "WrappingBitrateEstimator: Switching to transmission time offset RBE.");
  streams_.push_back(new Stream(this));
  streams_[0]->StopSending();
  streams_[1]->StopSending();
  EXPECT_TRUE(receiver_log_.Wait());
}
}  // namespace webrtc
