/*
 *  Copyright 2018 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 "absl/memory/memory.h"
#include "api/test/simulated_network.h"
#include "call/fake_network_pipe.h"
#include "call/simulated_network.h"
#include "test/call_test.h"
#include "test/field_trial.h"
#include "test/gtest.h"

namespace webrtc {
namespace {
enum : int {  // The first valid value is 1.
  kTransportSequenceNumberExtensionId = 1,
};
}  // namespace

class ProbingEndToEndTest : public test::CallTest {
 public:
  ProbingEndToEndTest() {
    RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
                                      kTransportSequenceNumberExtensionId));
  }
};

class ProbingTest : public test::EndToEndTest {
 public:
  explicit ProbingTest(int start_bitrate_bps)
      : clock_(Clock::GetRealTimeClock()),
        start_bitrate_bps_(start_bitrate_bps),
        state_(0),
        sender_call_(nullptr) {}

  void ModifySenderBitrateConfig(BitrateConstraints* bitrate_config) override {
    bitrate_config->start_bitrate_bps = start_bitrate_bps_;
  }

  void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
    sender_call_ = sender_call;
  }

 protected:
  Clock* const clock_;
  const int start_bitrate_bps_;
  int state_;
  Call* sender_call_;
};

// Flaky under MemorySanitizer: bugs.webrtc.org/7419
// Flaky on iOS bots: bugs.webrtc.org/7851
#if defined(MEMORY_SANITIZER)
TEST_F(ProbingEndToEndTest, DISABLED_InitialProbing) {
#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
TEST_F(ProbingEndToEndTest, DISABLED_InitialProbing) {
#else
TEST_F(ProbingEndToEndTest, InitialProbing) {
#endif

  class InitialProbingTest : public ProbingTest {
   public:
    explicit InitialProbingTest(
        bool* success,
        test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue)
        : ProbingTest(300000), success_(success), task_queue_(task_queue) {
      *success_ = false;
    }

    void PerformTest() override {
      int64_t start_time_ms = clock_->TimeInMilliseconds();
      do {
        if (clock_->TimeInMilliseconds() - start_time_ms > kTimeoutMs)
          break;

        Call::Stats stats;
        task_queue_->SendTask(
            [this, &stats]() { stats = sender_call_->GetStats(); });
        // Initial probing is done with a x3 and x6 multiplier of the start
        // bitrate, so a x4 multiplier is a high enough threshold.
        if (stats.send_bandwidth_bps > 4 * 300000) {
          *success_ = true;
          break;
        }
      } while (!observation_complete_.Wait(20));
    }

   private:
    const int kTimeoutMs = 1000;
    bool* const success_;
    test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
  };

  bool success = false;
  const int kMaxAttempts = 3;
  for (int i = 0; i < kMaxAttempts; ++i) {
    InitialProbingTest test(&success, &task_queue_);
    RunBaseTest(&test);
    if (success)
      return;
  }
  EXPECT_TRUE(success) << "Failed to perform mid initial probing ("
                       << kMaxAttempts << " attempts).";
}

// Fails on Linux MSan: bugs.webrtc.org/7428
#if defined(MEMORY_SANITIZER)
TEST_F(ProbingEndToEndTest, DISABLED_TriggerMidCallProbing) {
// Fails on iOS bots: bugs.webrtc.org/7851
#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
TEST_F(ProbingEndToEndTest, DISABLED_TriggerMidCallProbing) {
#else
TEST_F(ProbingEndToEndTest, TriggerMidCallProbing) {
#endif

  class TriggerMidCallProbingTest : public ProbingTest {
   public:
    TriggerMidCallProbingTest(
        test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue,
        bool* success)
        : ProbingTest(300000), success_(success), task_queue_(task_queue) {}

    void PerformTest() override {
      *success_ = false;
      int64_t start_time_ms = clock_->TimeInMilliseconds();
      do {
        if (clock_->TimeInMilliseconds() - start_time_ms > kTimeoutMs)
          break;

        Call::Stats stats;
        task_queue_->SendTask(
            [this, &stats]() { stats = sender_call_->GetStats(); });

        switch (state_) {
          case 0:
            if (stats.send_bandwidth_bps > 5 * 300000) {
              BitrateConstraints bitrate_config;
              bitrate_config.max_bitrate_bps = 100000;
              task_queue_->SendTask([this, &bitrate_config]() {
                sender_call_->GetTransportControllerSend()
                    ->SetSdpBitrateParameters(bitrate_config);
              });
              ++state_;
            }
            break;
          case 1:
            if (stats.send_bandwidth_bps < 110000) {
              BitrateConstraints bitrate_config;
              bitrate_config.max_bitrate_bps = 2500000;
              task_queue_->SendTask([this, &bitrate_config]() {
                sender_call_->GetTransportControllerSend()
                    ->SetSdpBitrateParameters(bitrate_config);
              });
              ++state_;
            }
            break;
          case 2:
            // During high cpu load the pacer will not be able to pace packets
            // at the correct speed, but if we go from 110 to 1250 kbps
            // in 5 seconds then it is due to probing.
            if (stats.send_bandwidth_bps > 1250000) {
              *success_ = true;
              observation_complete_.Set();
            }
            break;
        }
      } while (!observation_complete_.Wait(20));
    }

   private:
    const int kTimeoutMs = 5000;
    bool* const success_;
    test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
  };

  bool success = false;
  const int kMaxAttempts = 3;
  for (int i = 0; i < kMaxAttempts; ++i) {
    TriggerMidCallProbingTest test(&task_queue_, &success);
    RunBaseTest(&test);
    if (success)
      return;
  }
  EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts
                       << " attempts).";
}

#if defined(MEMORY_SANITIZER)
TEST_F(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) {
#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
TEST_F(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) {
#else
TEST_F(ProbingEndToEndTest, ProbeOnVideoEncoderReconfiguration) {
#endif

  class ReconfigureTest : public ProbingTest {
   public:
    ReconfigureTest(
        test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue,
        bool* success)
        : ProbingTest(50000), task_queue_(task_queue), success_(success) {}

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStream::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      encoder_config_ = encoder_config;
    }

    void OnVideoStreamsCreated(
        VideoSendStream* send_stream,
        const std::vector<VideoReceiveStream*>& receive_streams) override {
      send_stream_ = send_stream;
    }

    test::PacketTransport* CreateSendTransport(
        test::DEPRECATED_SingleThreadedTaskQueueForTesting* task_queue,
        Call* sender_call) override {
      auto network =
          absl::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig());
      send_simulated_network_ = network.get();
      return new test::PacketTransport(
          task_queue, sender_call, this, test::PacketTransport::kSender,
          CallTest::payload_type_map_,
          absl::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
                                             std::move(network)));
    }

    void PerformTest() override {
      *success_ = false;
      int64_t start_time_ms = clock_->TimeInMilliseconds();
      int64_t max_allocation_change_time_ms = -1;
      do {
        if (clock_->TimeInMilliseconds() - start_time_ms > kTimeoutMs)
          break;

        Call::Stats stats;
        task_queue_->SendTask(
            [this, &stats]() { stats = sender_call_->GetStats(); });

        switch (state_) {
          case 0:
            // Wait until initial probing has been completed (6 times start
            // bitrate).
            if (stats.send_bandwidth_bps >= 250000 &&
                stats.send_bandwidth_bps <= 350000) {
              BuiltInNetworkBehaviorConfig config;
              config.link_capacity_kbps = 200;
              send_simulated_network_->SetConfig(config);

              // In order to speed up the test we can interrupt exponential
              // probing by toggling the network availability. The alternative
              // is to wait for it to time out (1000 ms).
              sender_call_->GetTransportControllerSend()->OnNetworkAvailability(
                  false);
              sender_call_->GetTransportControllerSend()->OnNetworkAvailability(
                  true);

              ++state_;
            }
            break;
          case 1:
            if (stats.send_bandwidth_bps <= 200000) {
              // Initial probing finished. Increase link capacity and wait
              // until BWE ramped up enough to be in ALR. This takes a few
              // seconds.
              BuiltInNetworkBehaviorConfig config;
              config.link_capacity_kbps = 5000;
              send_simulated_network_->SetConfig(config);
              ++state_;
            }
            break;
          case 2:
            if (stats.send_bandwidth_bps > 240000) {
              // BWE ramped up enough to be in ALR. Setting higher max_bitrate
              // should trigger an allocation probe and fast ramp-up.
              encoder_config_->max_bitrate_bps = 2000000;
              encoder_config_->simulcast_layers[0].max_bitrate_bps = 1200000;
              task_queue_->SendTask([this]() {
                send_stream_->ReconfigureVideoEncoder(encoder_config_->Copy());
              });
              max_allocation_change_time_ms = clock_->TimeInMilliseconds();
              ++state_;
            }
            break;
          case 3:
            if (stats.send_bandwidth_bps >= 1000000) {
              EXPECT_LT(
                  clock_->TimeInMilliseconds() - max_allocation_change_time_ms,
                  kRampUpMaxDurationMs);
              *success_ = true;
              observation_complete_.Set();
            }
            break;
        }
      } while (!observation_complete_.Wait(20));
    }

   private:
    const int kTimeoutMs = 10000;
    const int kRampUpMaxDurationMs = 500;

    test::DEPRECATED_SingleThreadedTaskQueueForTesting* const task_queue_;
    bool* const success_;
    SimulatedNetwork* send_simulated_network_;
    VideoSendStream* send_stream_;
    VideoEncoderConfig* encoder_config_;
  };

  bool success = false;
  const int kMaxAttempts = 3;
  for (int i = 0; i < kMaxAttempts; ++i) {
    ReconfigureTest test(&task_queue_, &success);
    RunBaseTest(&test);
    if (success) {
      return;
    }
  }
  EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts
                       << " attempts).";
}

}  // namespace webrtc
