/*
 *  Copyright 2018 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/congestion_controller/goog_cc/test/goog_cc_printer.h"

#include <math.h>

#include <utility>

#include "absl/types/optional.h"
#include "modules/congestion_controller/goog_cc/alr_detector.h"
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
#include "modules/congestion_controller/goog_cc/trendline_estimator.h"
#include "modules/remote_bitrate_estimator/aimd_rate_control.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace {
void WriteTypedValue(RtcEventLogOutput* out, int value) {
  LogWriteFormat(out, "%i", value);
}
void WriteTypedValue(RtcEventLogOutput* out, double value) {
  LogWriteFormat(out, "%.6f", value);
}
void WriteTypedValue(RtcEventLogOutput* out, absl::optional<DataRate> value) {
  LogWriteFormat(out, "%.0f", value ? value->bytes_per_sec<double>() : NAN);
}
void WriteTypedValue(RtcEventLogOutput* out, absl::optional<DataSize> value) {
  LogWriteFormat(out, "%.0f", value ? value->bytes<double>() : NAN);
}
void WriteTypedValue(RtcEventLogOutput* out, absl::optional<TimeDelta> value) {
  LogWriteFormat(out, "%.3f", value ? value->seconds<double>() : NAN);
}
void WriteTypedValue(RtcEventLogOutput* out, absl::optional<Timestamp> value) {
  LogWriteFormat(out, "%.3f", value ? value->seconds<double>() : NAN);
}

template <typename F>
class TypedFieldLogger : public FieldLogger {
 public:
  TypedFieldLogger(std::string name, F&& getter)
      : name_(std::move(name)), getter_(std::forward<F>(getter)) {}
  const std::string& name() const override { return name_; }
  void WriteValue(RtcEventLogOutput* out) override {
    WriteTypedValue(out, getter_());
  }

 private:
  std::string name_;
  F getter_;
};

template <typename F>
FieldLogger* Log(std::string name, F&& getter) {
  return new TypedFieldLogger<F>(std::move(name), std::forward<F>(getter));
}

}  // namespace
GoogCcStatePrinter::GoogCcStatePrinter() {
  for (auto* logger : CreateLoggers()) {
    loggers_.emplace_back(logger);
  }
}

std::deque<FieldLogger*> GoogCcStatePrinter::CreateLoggers() {
  auto stable_estimate = [this] {
    return DataRate::kbps(
        controller_->delay_based_bwe_->rate_control_.link_capacity_
            .estimate_kbps_.value_or(-INFINITY));
  };
  auto rate_control_state = [this] {
    return static_cast<int>(
        controller_->delay_based_bwe_->rate_control_.rate_control_state_);
  };
  auto trend = [this] {
    return reinterpret_cast<TrendlineEstimator*>(
        controller_->delay_based_bwe_->delay_detector_.get());
  };
  auto acknowledged_rate = [this] {
    return controller_->acknowledged_bitrate_estimator_->bitrate();
  };
  std::deque<FieldLogger*> loggers({
      Log("time", [=] { return target_.at_time; }),
      Log("bandwidth", [=] { return target_.network_estimate.bandwidth; }),
      Log("rtt", [=] { return target_.network_estimate.round_trip_time; }),
      Log("target", [=] { return target_.target_rate; }),
      Log("pacing", [=] { return pacing_.data_rate(); }),
      Log("padding", [=] { return pacing_.pad_rate(); }),
      Log("window", [=] { return congestion_window_; }),
      Log("rate_control_state", [=] { return rate_control_state(); }),
      Log("stable_estimate", [=] { return stable_estimate(); }),
      Log("trendline", [=] { return trend()->prev_trend_; }),
      Log("trendline_modified_offset",
          [=] { return trend()->prev_modified_trend_; }),
      Log("trendline_offset_threshold", [=] { return trend()->threshold_; }),
      Log("acknowledged_rate", [=] { return acknowledged_rate(); }),
      Log("est_capacity", [=] { return est_.link_capacity; }),
      Log("est_capacity_dev", [=] { return est_.link_capacity_std_dev; }),
      Log("est_capacity_min", [=] { return est_.link_capacity_min; }),
      Log("est_cross_traffic", [=] { return est_.cross_traffic_ratio; }),
      Log("est_cross_delay", [=] { return est_.cross_delay_rate; }),
      Log("est_spike_delay", [=] { return est_.spike_delay_rate; }),
      Log("est_pre_buffer", [=] { return est_.pre_link_buffer_delay; }),
      Log("est_post_buffer", [=] { return est_.post_link_buffer_delay; }),
      Log("est_propagation", [=] { return est_.propagation_delay; }),
  });
  return loggers;
}
GoogCcStatePrinter::~GoogCcStatePrinter() = default;

void GoogCcStatePrinter::PrintHeaders(RtcEventLogOutput* log) {
  int ix = 0;
  for (const auto& logger : loggers_) {
    if (ix++)
      log->Write(" ");
    log->Write(logger->name());
  }
  log->Write("\n");
  log->Flush();
}

void GoogCcStatePrinter::PrintState(RtcEventLogOutput* log,
                                    GoogCcNetworkController* controller,
                                    Timestamp at_time) {
  controller_ = controller;
  auto state_update = controller_->GetNetworkState(at_time);
  target_ = state_update.target_rate.value();
  pacing_ = state_update.pacer_config.value();
  if (state_update.congestion_window)
    congestion_window_ = *state_update.congestion_window;
  if (controller_->network_estimator_) {
    est_ = controller_->network_estimator_->GetCurrentEstimate().value_or(
        NetworkStateEstimate());
  }

  int ix = 0;
  for (const auto& logger : loggers_) {
    if (ix++)
      log->Write(" ");
    logger->WriteValue(log);
  }

  log->Write("\n");
  log->Flush();
}

GoogCcDebugFactory::GoogCcDebugFactory()
    : GoogCcDebugFactory(GoogCcFactoryConfig()) {}

GoogCcDebugFactory::GoogCcDebugFactory(GoogCcFactoryConfig config)
    : GoogCcNetworkControllerFactory(std::move(config)) {}

std::unique_ptr<NetworkControllerInterface> GoogCcDebugFactory::Create(
    NetworkControllerConfig config) {
  RTC_CHECK(controller_ == nullptr);
  auto controller = GoogCcNetworkControllerFactory::Create(config);
  controller_ = static_cast<GoogCcNetworkController*>(controller.get());
  return controller;
}

void GoogCcDebugFactory::PrintState(const Timestamp at_time) {
  if (controller_ && log_writer_) {
    printer_.PrintState(log_writer_.get(), controller_, at_time);
  }
}

void GoogCcDebugFactory::AttachWriter(
    std::unique_ptr<RtcEventLogOutput> log_writer) {
  if (log_writer) {
    log_writer_ = std::move(log_writer);
    printer_.PrintHeaders(log_writer_.get());
  }
}

}  // namespace webrtc
