// Copyright 2014 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 <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/cast/sender/congestion_control.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {
namespace cast {

static const int kMaxBitrateConfigured = 5000000;
static const int kMinBitrateConfigured = 500000;
static const int64_t kFrameDelayMs = 33;
static const double kMaxFrameRate = 1000.0 / kFrameDelayMs;
static const int64_t kStartMillisecond = INT64_C(12345678900000);
static const double kTargetEmptyBufferFraction = 0.9;

class CongestionControlTest : public ::testing::Test {
 protected:
  CongestionControlTest()
      : task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)) {
    testing_clock_.Advance(
        base::TimeDelta::FromMilliseconds(kStartMillisecond));
    congestion_control_.reset(
        NewAdaptiveCongestionControl(&testing_clock_, kMaxBitrateConfigured,
                                     kMinBitrateConfigured, kMaxFrameRate));
    const int max_unacked_frames = 10;
    const base::TimeDelta target_playout_delay =
        (max_unacked_frames - 1) * base::TimeDelta::FromSeconds(1) /
        kMaxFrameRate;
    congestion_control_->UpdateTargetPlayoutDelay(target_playout_delay);
  }

  void AckFrame(FrameId frame_id) {
    congestion_control_->AckFrame(frame_id, testing_clock_.NowTicks());
  }

  void Run(int num_frames, size_t frame_size, base::TimeDelta rtt,
           base::TimeDelta frame_delay, base::TimeDelta ack_time) {
    const FrameId end = FrameId::first() + num_frames;
    for (frame_id_ = FrameId::first(); frame_id_ < end; frame_id_++) {
      congestion_control_->UpdateRtt(rtt);
      congestion_control_->SendFrameToTransport(frame_id_, frame_size,
                                                testing_clock_.NowTicks());
      task_runner_->PostDelayedTask(
          FROM_HERE, base::Bind(&CongestionControlTest::AckFrame,
                                base::Unretained(this), frame_id_),
          ack_time);
      task_runner_->Sleep(frame_delay);
    }
  }

  base::SimpleTestTickClock testing_clock_;
  std::unique_ptr<CongestionControl> congestion_control_;
  scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
  FrameId frame_id_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CongestionControlTest);
};

// Tests that AdaptiveCongestionControl returns reasonable bitrates based on
// estimations of network bandwidth and how much is in-flight (i.e, using the
// "target buffer fill" model).
TEST_F(CongestionControlTest, SimpleRun) {
  uint32_t frame_size = 10000 * 8;
  Run(500, frame_size, base::TimeDelta::FromMilliseconds(10),
      base::TimeDelta::FromMilliseconds(kFrameDelayMs),
      base::TimeDelta::FromMilliseconds(45));
  // Empty the buffer.
  task_runner_->Sleep(base::TimeDelta::FromMilliseconds(100));

  uint32_t safe_bitrate = frame_size * 1000 / kFrameDelayMs;
  uint32_t bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction, bitrate,
              safe_bitrate * 0.05);

  bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(200),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3, bitrate,
              safe_bitrate * 0.05);

  bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(100),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 1 / 3, bitrate,
              safe_bitrate * 0.05);

  // Add a large (100ms) frame.
  congestion_control_->SendFrameToTransport(
      frame_id_++, safe_bitrate * 100 / 1000, testing_clock_.NowTicks());

  // Results should show that we have ~200ms to send.
  bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3, bitrate,
              safe_bitrate * 0.05);

  // Add another large (100ms) frame.
  congestion_control_->SendFrameToTransport(
      frame_id_++, safe_bitrate * 100 / 1000, testing_clock_.NowTicks());

  // Results should show that we have ~100ms to send.
  bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 1 / 3, bitrate,
              safe_bitrate * 0.05);

  // Ack the last frame.
  std::vector<FrameId> received_frames;
  received_frames.push_back(frame_id_ - 1);
  congestion_control_->AckLaterFrames(received_frames,
                                      testing_clock_.NowTicks());

  // Results should show that we have ~200ms to send.
  bitrate = congestion_control_->GetBitrate(
      testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
      base::TimeDelta::FromMilliseconds(300));
  EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3, bitrate,
              safe_bitrate * 0.05);
}

}  // namespace cast
}  // namespace media
}  // namespace cobalt
