/*
 *  Copyright (c) 2014 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 "modules/bitrate_controller/send_side_bandwidth_estimation.h"
#include "logging/rtc_event_log/events/rtc_event.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

MATCHER(LossBasedBweUpdateWithBitrateOnly, "") {
  if (arg->GetType() != RtcEvent::Type::BweUpdateLossBased) {
    return false;
  }
  auto bwe_event = static_cast<RtcEventBweUpdateLossBased*>(arg);
  return bwe_event->bitrate_bps() > 0 && bwe_event->fraction_loss() == 0;
}

MATCHER(LossBasedBweUpdateWithBitrateAndLossFraction, "") {
  if (arg->GetType() != RtcEvent::Type::BweUpdateLossBased) {
    return false;
  }
  auto bwe_event = static_cast<RtcEventBweUpdateLossBased*>(arg);
  return bwe_event->bitrate_bps() > 0 && bwe_event->fraction_loss() > 0;
}

void TestProbing(bool use_delay_based) {
  testing::NiceMock<MockRtcEventLog> event_log;
  SendSideBandwidthEstimation bwe(&event_log);
  int64_t now_ms = 0;
  bwe.SetMinMaxBitrate(DataRate::bps(100000), DataRate::bps(1500000));
  bwe.SetSendBitrate(DataRate::bps(200000), Timestamp::ms(now_ms));

  const int kRembBps = 1000000;
  const int kSecondRembBps = kRembBps + 500000;

  bwe.UpdateReceiverBlock(0, TimeDelta::ms(50), 1, Timestamp::ms(now_ms));

  // Initial REMB applies immediately.
  if (use_delay_based) {
    bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
                                 DataRate::bps(kRembBps));
  } else {
    bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms), DataRate::bps(kRembBps));
  }
  bwe.UpdateEstimate(Timestamp::ms(now_ms));
  int bitrate;
  uint8_t fraction_loss;
  int64_t rtt;
  bwe.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
  EXPECT_EQ(kRembBps, bitrate);

  // Second REMB doesn't apply immediately.
  now_ms += 2001;
  if (use_delay_based) {
    bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
                                 DataRate::bps(kSecondRembBps));
  } else {
    bwe.UpdateReceiverEstimate(Timestamp::ms(now_ms),
                               DataRate::bps(kSecondRembBps));
  }
  bwe.UpdateEstimate(Timestamp::ms(now_ms));
  bitrate = 0;
  bwe.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
  EXPECT_EQ(kRembBps, bitrate);
}

TEST(SendSideBweTest, InitialRembWithProbing) {
  TestProbing(false);
}

TEST(SendSideBweTest, InitialDelayBasedBweWithProbing) {
  TestProbing(true);
}

TEST(SendSideBweTest, DoesntReapplyBitrateDecreaseWithoutFollowingRemb) {
  MockRtcEventLog event_log;
  EXPECT_CALL(event_log, LogProxy(LossBasedBweUpdateWithBitrateOnly()))
      .Times(1);
  EXPECT_CALL(event_log,
              LogProxy(LossBasedBweUpdateWithBitrateAndLossFraction()))
      .Times(1);
  SendSideBandwidthEstimation bwe(&event_log);
  static const int kMinBitrateBps = 100000;
  static const int kInitialBitrateBps = 1000000;
  int64_t now_ms = 1000;
  bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps), DataRate::bps(1500000));
  bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));

  static const uint8_t kFractionLoss = 128;
  static const int64_t kRttMs = 50;
  now_ms += 10000;

  int bitrate_bps;
  uint8_t fraction_loss;
  int64_t rtt_ms;
  bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
  EXPECT_EQ(kInitialBitrateBps, bitrate_bps);
  EXPECT_EQ(0, fraction_loss);
  EXPECT_EQ(0, rtt_ms);

  // Signal heavy loss to go down in bitrate.
  bwe.UpdateReceiverBlock(kFractionLoss, TimeDelta::ms(kRttMs), 100,
                          Timestamp::ms(now_ms));
  // Trigger an update 2 seconds later to not be rate limited.
  now_ms += 1000;
  bwe.UpdateEstimate(Timestamp::ms(now_ms));

  bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
  EXPECT_LT(bitrate_bps, kInitialBitrateBps);
  // Verify that the obtained bitrate isn't hitting the min bitrate, or this
  // test doesn't make sense. If this ever happens, update the thresholds or
  // loss rates so that it doesn't hit min bitrate after one bitrate update.
  EXPECT_GT(bitrate_bps, kMinBitrateBps);
  EXPECT_EQ(kFractionLoss, fraction_loss);
  EXPECT_EQ(kRttMs, rtt_ms);

  // Triggering an update shouldn't apply further downgrade nor upgrade since
  // there's no intermediate receiver block received indicating whether this is
  // currently good or not.
  int last_bitrate_bps = bitrate_bps;
  // Trigger an update 2 seconds later to not be rate limited (but it still
  // shouldn't update).
  now_ms += 1000;
  bwe.UpdateEstimate(Timestamp::ms(now_ms));
  bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);

  EXPECT_EQ(last_bitrate_bps, bitrate_bps);
  // The old loss rate should still be applied though.
  EXPECT_EQ(kFractionLoss, fraction_loss);
  EXPECT_EQ(kRttMs, rtt_ms);
}

TEST(SendSideBweTest, SettingSendBitrateOverridesDelayBasedEstimate) {
  ::testing::NiceMock<MockRtcEventLog> event_log;
  SendSideBandwidthEstimation bwe(&event_log);
  static const int kMinBitrateBps = 10000;
  static const int kMaxBitrateBps = 10000000;
  static const int kInitialBitrateBps = 300000;
  static const int kDelayBasedBitrateBps = 350000;
  static const int kForcedHighBitrate = 2500000;

  int64_t now_ms = 0;
  int bitrate_bps;
  uint8_t fraction_loss;
  int64_t rtt_ms;

  bwe.SetMinMaxBitrate(DataRate::bps(kMinBitrateBps),
                       DataRate::bps(kMaxBitrateBps));
  bwe.SetSendBitrate(DataRate::bps(kInitialBitrateBps), Timestamp::ms(now_ms));

  bwe.UpdateDelayBasedEstimate(Timestamp::ms(now_ms),
                               DataRate::bps(kDelayBasedBitrateBps));
  bwe.UpdateEstimate(Timestamp::ms(now_ms));
  bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
  EXPECT_GE(bitrate_bps, kInitialBitrateBps);
  EXPECT_LE(bitrate_bps, kDelayBasedBitrateBps);

  bwe.SetSendBitrate(DataRate::bps(kForcedHighBitrate), Timestamp::ms(now_ms));
  bwe.CurrentEstimate(&bitrate_bps, &fraction_loss, &rtt_ms);
  EXPECT_EQ(bitrate_bps, kForcedHighBitrate);
}

}  // namespace webrtc
