/*
 *  Copyright (c) 2022 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/audio_coding/neteq/packet_arrival_history.h"

#include <algorithm>

#include "api/neteq/tick_timer.h"

namespace webrtc {

PacketArrivalHistory::PacketArrivalHistory(int window_size_ms)
    : window_size_ms_(window_size_ms) {}

void PacketArrivalHistory::Insert(uint32_t rtp_timestamp,
                                  int64_t arrival_time_ms) {
  RTC_DCHECK(sample_rate_khz_ > 0);
  int64_t unwrapped_rtp_timestamp = timestamp_unwrapper_.Unwrap(rtp_timestamp);
  if (!newest_rtp_timestamp_ ||
      unwrapped_rtp_timestamp > *newest_rtp_timestamp_) {
    newest_rtp_timestamp_ = unwrapped_rtp_timestamp;
  }
  history_.emplace_back(unwrapped_rtp_timestamp / sample_rate_khz_,
                        arrival_time_ms);
  MaybeUpdateCachedArrivals(history_.back());
  while (history_.front().rtp_timestamp_ms + window_size_ms_ <
         unwrapped_rtp_timestamp / sample_rate_khz_) {
    if (&history_.front() == min_packet_arrival_) {
      min_packet_arrival_ = nullptr;
    }
    if (&history_.front() == max_packet_arrival_) {
      max_packet_arrival_ = nullptr;
    }
    history_.pop_front();
  }
  if (!min_packet_arrival_ || !max_packet_arrival_) {
    for (const PacketArrival& packet : history_) {
      MaybeUpdateCachedArrivals(packet);
    }
  }
}

void PacketArrivalHistory::MaybeUpdateCachedArrivals(
    const PacketArrival& packet_arrival) {
  if (!min_packet_arrival_ || packet_arrival <= *min_packet_arrival_) {
    min_packet_arrival_ = &packet_arrival;
  }
  if (!max_packet_arrival_ || packet_arrival >= *max_packet_arrival_) {
    max_packet_arrival_ = &packet_arrival;
  }
}

void PacketArrivalHistory::Reset() {
  history_.clear();
  min_packet_arrival_ = nullptr;
  max_packet_arrival_ = nullptr;
  timestamp_unwrapper_.Reset();
  newest_rtp_timestamp_ = absl::nullopt;
}

int PacketArrivalHistory::GetDelayMs(uint32_t rtp_timestamp,
                                     int64_t time_ms) const {
  RTC_DCHECK(sample_rate_khz_ > 0);
  int64_t unwrapped_rtp_timestamp_ms =
      timestamp_unwrapper_.PeekUnwrap(rtp_timestamp) / sample_rate_khz_;
  PacketArrival packet(unwrapped_rtp_timestamp_ms, time_ms);
  return GetPacketArrivalDelayMs(packet);
}

int PacketArrivalHistory::GetMaxDelayMs() const {
  if (!max_packet_arrival_) {
    return 0;
  }
  return GetPacketArrivalDelayMs(*max_packet_arrival_);
}

bool PacketArrivalHistory::IsNewestRtpTimestamp(uint32_t rtp_timestamp) const {
  if (!newest_rtp_timestamp_) {
    return false;
  }
  int64_t unwrapped_rtp_timestamp =
      timestamp_unwrapper_.PeekUnwrap(rtp_timestamp);
  return unwrapped_rtp_timestamp == *newest_rtp_timestamp_;
}

int PacketArrivalHistory::GetPacketArrivalDelayMs(
    const PacketArrival& packet_arrival) const {
  if (!min_packet_arrival_) {
    return 0;
  }
  return std::max(static_cast<int>(packet_arrival.arrival_time_ms -
                                   min_packet_arrival_->arrival_time_ms -
                                   (packet_arrival.rtp_timestamp_ms -
                                    min_packet_arrival_->rtp_timestamp_ms)),
                  0);
}

}  // namespace webrtc
