/*
 *  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 "webrtc/modules/pacing/bitrate_prober.h"

#include <assert.h>
#include <algorithm>
#include <limits>
#include <sstream>

#include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/system_wrappers/include/logging.h"

namespace webrtc {

namespace {
int ComputeDeltaFromBitrate(size_t packet_size, int bitrate_bps) {
  assert(bitrate_bps > 0);
  // Compute the time delta needed to send packet_size bytes at bitrate_bps
  // bps. Result is in milliseconds.
  return static_cast<int>(1000ll * static_cast<int64_t>(packet_size) * 8ll /
      bitrate_bps);
}
}  // namespace

BitrateProber::BitrateProber()
    : probing_state_(kDisabled),
      packet_size_last_send_(0),
      time_last_send_ms_(-1) {
}

void BitrateProber::SetEnabled(bool enable) {
  if (enable) {
    if (probing_state_ == kDisabled) {
      probing_state_ = kAllowedToProbe;
      LOG(LS_INFO) << "Initial bandwidth probing enabled";
    }
  } else {
    probing_state_ = kDisabled;
    LOG(LS_INFO) << "Initial bandwidth probing disabled";
  }
}

bool BitrateProber::IsProbing() const {
  return probing_state_ == kProbing;
}

void BitrateProber::MaybeInitializeProbe(int bitrate_bps) {
  if (probing_state_ != kAllowedToProbe)
    return;
  probe_bitrates_.clear();
  // Max number of packets used for probing.
  const int kMaxNumProbes = 2;
  const int kPacketsPerProbe = 5;
  const float kProbeBitrateMultipliers[kMaxNumProbes] = {3, 6};
  int bitrates_bps[kMaxNumProbes];
  std::stringstream bitrate_log;
  bitrate_log << "Start probing for bandwidth, bitrates:";
  for (int i = 0; i < kMaxNumProbes; ++i) {
    bitrates_bps[i] = kProbeBitrateMultipliers[i] * bitrate_bps;
    bitrate_log << " " << bitrates_bps[i];
    // We need one extra to get 5 deltas for the first probe.
    if (i == 0)
      probe_bitrates_.push_back(bitrates_bps[i]);
    for (int j = 0; j < kPacketsPerProbe; ++j)
      probe_bitrates_.push_back(bitrates_bps[i]);
  }
  bitrate_log << ", num packets: " << probe_bitrates_.size();
  LOG(LS_INFO) << bitrate_log.str().c_str();
  probing_state_ = kProbing;
}

int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
  if (probing_state_ != kDisabled && probe_bitrates_.empty()) {
    probing_state_ = kWait;
  }
  if (probe_bitrates_.empty()) {
    // No probe started, or waiting for next probe.
    return -1;
  }
  int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
  // We will send the first probe packet immediately if no packet has been
  // sent before.
  int time_until_probe_ms = 0;
  if (packet_size_last_send_ > PacedSender::kMinProbePacketSize &&
      probing_state_ == kProbing) {
    int next_delta_ms = ComputeDeltaFromBitrate(packet_size_last_send_,
                                                probe_bitrates_.front());
    time_until_probe_ms = next_delta_ms - elapsed_time_ms;
    // There is no point in trying to probe with less than 1 ms between packets
    // as it essentially means trying to probe at infinite bandwidth.
    const int kMinProbeDeltaMs = 1;
    // If we have waited more than 3 ms for a new packet to probe with we will
    // consider this probing session over.
    const int kMaxProbeDelayMs = 3;
    if (next_delta_ms < kMinProbeDeltaMs ||
        time_until_probe_ms < -kMaxProbeDelayMs) {
      // We currently disable probing after the first probe, as we only want
      // to probe at the beginning of a connection. We should set this to
      // kWait if we later want to probe periodically.
      probing_state_ = kWait;
      LOG(LS_INFO) << "Next delta too small, stop probing.";
      time_until_probe_ms = 0;
    }
  }
  return std::max(time_until_probe_ms, 0);
}

size_t BitrateProber::RecommendedPacketSize() const {
  return packet_size_last_send_;
}

void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
  assert(packet_size > 0);
  packet_size_last_send_ = packet_size;
  time_last_send_ms_ = now_ms;
  if (probing_state_ != kProbing)
    return;
  if (!probe_bitrates_.empty())
    probe_bitrates_.pop_front();
}
}  // namespace webrtc
