// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/moqt/moqt_bitrate_adjuster.h"

#include "quiche/quic/core/quic_bandwidth.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/test_tools/mock_clock.h"
#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/web_transport/test_tools/mock_web_transport.h"
#include "quiche/web_transport/web_transport.h"

namespace moqt::test {
namespace {

using ::quic::QuicBandwidth;
using ::quic::QuicTimeDelta;
using ::testing::_;

// Simple adjustable object that just keeps track of whatever value has been
// assigned to it, and has a mock method to notify of it changing.
class MockBitrateAdjustable : public BitrateAdjustable {
 public:
  explicit MockBitrateAdjustable(QuicBandwidth initial_bitrate)
      : bitrate_(initial_bitrate) {}

  quic::QuicBandwidth GetCurrentBitrate() const { return bitrate_; }
  bool CouldUseExtraBandwidth() override { return true; }
  void ConsiderAdjustingBitrate(QuicBandwidth bandwidth,
                                BitrateAdjustmentType /*type*/) override {
    bitrate_ = bandwidth;
    OnBitrateAdjusted(bandwidth);
  }

  MOCK_METHOD(void, OnBitrateAdjusted, (QuicBandwidth new_bitrate), ());

 private:
  QuicBandwidth bitrate_;
};

constexpr QuicBandwidth kDefaultBitrate =
    QuicBandwidth::FromBitsPerSecond(2000);
constexpr QuicTimeDelta kDefaultRtt = QuicTimeDelta::FromMilliseconds(20);
constexpr QuicTimeDelta kDefaultTimeScale = QuicTimeDelta::FromSeconds(1);

class MoqtBitrateAdjusterTest : public quiche::test::QuicheTest {
 protected:
  MoqtBitrateAdjusterTest()
      : adjustable_(kDefaultBitrate),
        adjuster_(&clock_, &session_, &adjustable_) {
    stats_.min_rtt = stats_.smoothed_rtt = kDefaultRtt.ToAbsl();
    stats_.estimated_send_rate_bps = (1.2 * kDefaultBitrate).ToBitsPerSecond();
    ON_CALL(session_, GetSessionStats()).WillByDefault([this] {
      return stats_;
    });

    clock_.AdvanceTime(quic::QuicTimeDelta::FromSeconds(10));
    adjuster_.OnObjectAckSupportKnown(kDefaultTimeScale);
  }

  MockBitrateAdjustable adjustable_;
  webtransport::SessionStats stats_;
  quic::MockClock clock_;
  webtransport::test::MockSession session_;
  MoqtBitrateAdjuster adjuster_;
};

TEST_F(MoqtBitrateAdjusterTest, IgnoreCallsBeforeStart) {
  MoqtBitrateAdjuster uninitialized_adjuster(&clock_, &session_, &adjustable_);
  uninitialized_adjuster.OnNewObjectEnqueued(Location(1, 0));
  uninitialized_adjuster.OnObjectAckReceived(
      Location(1, 0), QuicTimeDelta::FromMilliseconds(100));
}

TEST_F(MoqtBitrateAdjusterTest, SteadyState) {
  // The fact that estimated bitrate is 1bps should not matter, since we never
  // have a reason to adjust down.
  stats_.estimated_send_rate_bps = 1;

  EXPECT_CALL(adjustable_, OnBitrateAdjusted).Times(0);
  for (int i = 0; i < 250; ++i) {
    clock_.AdvanceTime(kDefaultRtt);
    for (int j = 0; j < 10; ++j) {
      adjuster_.OnObjectAckReceived(Location(i, j), kDefaultTimeScale * 0.9);
    }
  }
}

TEST_F(MoqtBitrateAdjusterTest, AdjustDownOnce) {
  stats_.estimated_send_rate_bps = (0.5 * kDefaultBitrate).ToBitsPerSecond();

  // First time will be skipped, since we aren't far enough into connection.
  EXPECT_CALL(adjustable_, OnBitrateAdjusted(_)).Times(0);
  adjuster_.OnObjectAckReceived(Location(0, 0),
                                QuicTimeDelta::FromMilliseconds(-1));

  clock_.AdvanceTime(100 * kDefaultRtt);
  EXPECT_CALL(adjustable_, OnBitrateAdjusted(_))
      .WillOnce([](QuicBandwidth new_bitrate) {
        EXPECT_LT(new_bitrate, kDefaultBitrate);
      });
  adjuster_.OnObjectAckReceived(Location(0, 1),
                                QuicTimeDelta::FromMilliseconds(-1));
}

TEST_F(MoqtBitrateAdjusterTest, AdjustDownTwice) {
  int adjusted_times = 0;
  EXPECT_CALL(adjustable_, OnBitrateAdjusted(_)).WillRepeatedly([&] {
    ++adjusted_times;
  });

  clock_.AdvanceTime(100 * kDefaultRtt);
  stats_.estimated_send_rate_bps = (0.5 * kDefaultBitrate).ToBitsPerSecond();
  adjuster_.OnObjectAckReceived(Location(0, 0),
                                QuicTimeDelta::FromMilliseconds(-1));
  EXPECT_EQ(adjusted_times, 1);

  clock_.AdvanceTime(100 * kDefaultRtt);
  stats_.estimated_send_rate_bps = (0.25 * kDefaultBitrate).ToBitsPerSecond();
  adjuster_.OnObjectAckReceived(Location(0, 1),
                                QuicTimeDelta::FromMilliseconds(-1));
  EXPECT_EQ(adjusted_times, 2);
}

TEST_F(MoqtBitrateAdjusterTest, OutOfOrderAckIgnored) {
  int adjusted_times = 0;
  EXPECT_CALL(adjustable_, OnBitrateAdjusted).WillRepeatedly([&] {
    ++adjusted_times;
  });

  clock_.AdvanceTime(100 * kDefaultRtt);
  stats_.estimated_send_rate_bps = (0.5 * kDefaultBitrate).ToBitsPerSecond();
  adjuster_.OnObjectAckReceived(Location(0, 1),
                                QuicTimeDelta::FromMilliseconds(-1));
  EXPECT_EQ(adjusted_times, 1);

  clock_.AdvanceTime(100 * kDefaultRtt);
  stats_.estimated_send_rate_bps = (0.25 * kDefaultBitrate).ToBitsPerSecond();
  adjuster_.OnObjectAckReceived(Location(0, 0),
                                QuicTimeDelta::FromMilliseconds(-1));
  EXPECT_EQ(adjusted_times, 1);
}

TEST_F(MoqtBitrateAdjusterTest, Reordering) {
  adjuster_.parameters().max_out_of_order_objects = 1;
  clock_.AdvanceTime(100 * kDefaultRtt);
  stats_.estimated_send_rate_bps = (0.5 * kDefaultBitrate).ToBitsPerSecond();

  adjuster_.OnNewObjectEnqueued(Location(0, 0));
  adjuster_.OnNewObjectEnqueued(Location(0, 1));
  adjuster_.OnNewObjectEnqueued(Location(0, 2));

  EXPECT_CALL(adjustable_, OnBitrateAdjusted);
  adjuster_.OnObjectAckReceived(Location(0, 2), kDefaultTimeScale);
}

TEST_F(MoqtBitrateAdjusterTest, ShouldIgnoreBitrateAdjustment) {
  constexpr quic::QuicBandwidth kOldBandwith =
      quic::QuicBandwidth::FromKBitsPerSecond(1024);
  constexpr float kMinChange = 0.01;
  EXPECT_FALSE(ShouldIgnoreBitrateAdjustment(kOldBandwith * 0.5,
                                             BitrateAdjustmentType::kDown,
                                             kOldBandwith, kMinChange));
  EXPECT_FALSE(ShouldIgnoreBitrateAdjustment(kOldBandwith * 1.5,
                                             BitrateAdjustmentType::kUp,
                                             kOldBandwith, kMinChange));

  // Always ignore change if new bandwidth is the old bandwidth.
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(
      kOldBandwith, BitrateAdjustmentType::kUp, kOldBandwith, kMinChange));
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(
      kOldBandwith, BitrateAdjustmentType::kDown, kOldBandwith, kMinChange));

  // Ignore very small changes to bitrate.
  const quic::QuicBandwidth kTinyDelta =
      quic::QuicBandwidth::FromBitsPerSecond(1);
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(kOldBandwith - kTinyDelta,
                                            BitrateAdjustmentType::kDown,
                                            kOldBandwith, kMinChange));
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(kOldBandwith + kTinyDelta,
                                            BitrateAdjustmentType::kUp,
                                            kOldBandwith, kMinChange));

  // Ignore if the direction of change stated by the bitrate adjuster is
  // different from the actual direction suggested by the new bitrate value.
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(kOldBandwith * 0.5,
                                            BitrateAdjustmentType::kUp,
                                            kOldBandwith, kMinChange));
  EXPECT_TRUE(ShouldIgnoreBitrateAdjustment(kOldBandwith * 1.5,
                                            BitrateAdjustmentType::kDown,
                                            kOldBandwith, kMinChange));
}

}  // namespace
}  // namespace moqt::test
