/*
 *  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/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
