/*
 *
 * Copyright 2016 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#include "src/core/lib/transport/bdp_estimator.h"

#include <inttypes.h>
#include <stdlib.h>

#include "src/core/lib/gpr/useful.h"

grpc_core::TraceFlag grpc_bdp_estimator_trace(false, "bdp_estimator");

namespace grpc_core {

BdpEstimator::BdpEstimator(const char* name)
    : ping_state_(PingState::UNSCHEDULED),
      accumulator_(0),
      estimate_(65536),
      ping_start_time_(gpr_time_0(GPR_CLOCK_MONOTONIC)),
      inter_ping_delay_(100.0),  // start at 100ms
      stable_estimate_count_(0),
      bw_est_(0),
      name_(name) {}

grpc_millis BdpEstimator::CompletePing() {
  gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
  gpr_timespec dt_ts = gpr_time_sub(now, ping_start_time_);
  double dt = static_cast<double>(dt_ts.tv_sec) +
              1e-9 * static_cast<double>(dt_ts.tv_nsec);
  double bw = dt > 0 ? (static_cast<double>(accumulator_) / dt) : 0;
  int start_inter_ping_delay = inter_ping_delay_;
  if (grpc_bdp_estimator_trace.enabled()) {
    gpr_log(GPR_INFO,
            "bdp[%s]:complete acc=%" PRId64 " est=%" PRId64
            " dt=%lf bw=%lfMbs bw_est=%lfMbs",
            name_, accumulator_, estimate_, dt, bw / 125000.0,
            bw_est_ / 125000.0);
  }
  GPR_ASSERT(ping_state_ == PingState::STARTED);
  if (accumulator_ > 2 * estimate_ / 3 && bw > bw_est_) {
    estimate_ = GPR_MAX(accumulator_, estimate_ * 2);
    bw_est_ = bw;
    if (grpc_bdp_estimator_trace.enabled()) {
      gpr_log(GPR_INFO, "bdp[%s]: estimate increased to %" PRId64, name_,
              estimate_);
    }
    inter_ping_delay_ /= 2;  // if the ping estimate changes,
                             // exponentially get faster at probing
  } else if (inter_ping_delay_ < 10000) {
    stable_estimate_count_++;
    if (stable_estimate_count_ >= 2) {
      inter_ping_delay_ +=
          100 + static_cast<int>(rand() * 100.0 /
                                 RAND_MAX);  // if the ping estimate is steady,
                                             // slowly ramp down the probe time
    }
  }
  if (start_inter_ping_delay != inter_ping_delay_) {
    stable_estimate_count_ = 0;
    if (grpc_bdp_estimator_trace.enabled()) {
      gpr_log(GPR_INFO, "bdp[%s]:update_inter_time to %dms", name_,
              inter_ping_delay_);
    }
  }
  ping_state_ = PingState::UNSCHEDULED;
  accumulator_ = 0;
  return grpc_core::ExecCtx::Get()->Now() + inter_ping_delay_;
}

}  // namespace grpc_core
