/*
 *  Copyright (c) 2016 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/alr_detector.h"

#include <cstdint>
#include <cstdio>

#include "absl/memory/memory.h"
#include "logging/rtc_event_log/events/rtc_event.h"
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/time_utils.h"

namespace webrtc {

namespace {
absl::optional<AlrExperimentSettings> GetExperimentSettings(
    const WebRtcKeyValueConfig* key_value_config) {
  RTC_CHECK(AlrExperimentSettings::MaxOneFieldTrialEnabled(*key_value_config));
  absl::optional<AlrExperimentSettings> experiment_settings =
      AlrExperimentSettings::CreateFromFieldTrial(
          *key_value_config,
          AlrExperimentSettings::kScreenshareProbingBweExperimentName);
  if (!experiment_settings) {
    experiment_settings = AlrExperimentSettings::CreateFromFieldTrial(
        *key_value_config,
        AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
  }
  return experiment_settings;
}
}  //  namespace

AlrDetector::AlrDetector(const WebRtcKeyValueConfig* key_value_config)
    : AlrDetector(key_value_config,
                  nullptr,
                  GetExperimentSettings(key_value_config)) {}

AlrDetector::AlrDetector(const WebRtcKeyValueConfig* key_value_config,
                         RtcEventLog* event_log)
    : AlrDetector(key_value_config,
                  event_log,
                  GetExperimentSettings(key_value_config)) {}

AlrDetector::AlrDetector(
    const WebRtcKeyValueConfig* key_value_config,
    RtcEventLog* event_log,
    absl::optional<AlrExperimentSettings> experiment_settings)
    : bandwidth_usage_ratio_(
          "bw_usage",
          experiment_settings
              ? experiment_settings->alr_bandwidth_usage_percent / 100.0
              : kDefaultBandwidthUsageRatio),
      start_budget_level_ratio_(
          "start",
          experiment_settings
              ? experiment_settings->alr_start_budget_level_percent / 100.0
              : kDefaultStartBudgetLevelRatio),
      stop_budget_level_ratio_(
          "stop",
          experiment_settings
              ? experiment_settings->alr_stop_budget_level_percent / 100.0
              : kDefaultStopBudgetLevelRatio),
      alr_budget_(0, true),
      event_log_(event_log) {
  ParseFieldTrial({&bandwidth_usage_ratio_, &start_budget_level_ratio_,
                   &stop_budget_level_ratio_},
                  key_value_config->Lookup("WebRTC-AlrDetectorParameters"));
}

AlrDetector::~AlrDetector() {}

void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t send_time_ms) {
  if (!last_send_time_ms_.has_value()) {
    last_send_time_ms_ = send_time_ms;
    // Since the duration for sending the bytes is unknwon, return without
    // updating alr state.
    return;
  }
  int64_t delta_time_ms = send_time_ms - *last_send_time_ms_;
  last_send_time_ms_ = send_time_ms;

  alr_budget_.UseBudget(bytes_sent);
  alr_budget_.IncreaseBudget(delta_time_ms);
  bool state_changed = false;
  if (alr_budget_.budget_ratio() > start_budget_level_ratio_ &&
      !alr_started_time_ms_) {
    alr_started_time_ms_.emplace(rtc::TimeMillis());
    state_changed = true;
  } else if (alr_budget_.budget_ratio() < stop_budget_level_ratio_ &&
             alr_started_time_ms_) {
    state_changed = true;
    alr_started_time_ms_.reset();
  }
  if (event_log_ && state_changed) {
    event_log_->Log(
        absl::make_unique<RtcEventAlrState>(alr_started_time_ms_.has_value()));
  }
}

void AlrDetector::SetEstimatedBitrate(int bitrate_bps) {
  RTC_DCHECK(bitrate_bps);
  int target_rate_kbps =
      static_cast<double>(bitrate_bps) * bandwidth_usage_ratio_ / 1000;
  alr_budget_.set_target_rate_kbps(target_rate_kbps);
}

absl::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime()
    const {
  return alr_started_time_ms_;
}

}  // namespace webrtc
