/*
 *  Copyright (c) 2023 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 "test/jitter/delay_variation_calculator.h"

#include <optional>
#include <string>

#include "api/units/frequency.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace test {

namespace {
constexpr Frequency k90000Hz = Frequency::Hertz(90000);
}  // namespace

void DelayVariationCalculator::Insert(
    uint32_t rtp_timestamp,
    Timestamp arrival_time,
    DataSize size,
    std::optional<int> spatial_layer,
    std::optional<int> temporal_layer,
    std::optional<VideoFrameType> frame_type) {
  Frame frame{.rtp_timestamp = rtp_timestamp,
              .unwrapped_rtp_timestamp = unwrapper_.Unwrap(rtp_timestamp),
              .arrival_time = arrival_time,
              .size = size,
              .spatial_layer = spatial_layer,
              .temporal_layer = temporal_layer,
              .frame_type = frame_type};
  // Using RTP timestamp as the time series sample identifier allows for
  // cross-correlating time series logged by different objects at different
  // arrival timestamps.
  Timestamp sample_time =
      Timestamp::Millis((frame.unwrapped_rtp_timestamp / k90000Hz).ms());
  MetadataT sample_metadata = BuildMetadata(frame);
  if (!prev_frame_) {
    InsertFirstFrame(frame, sample_time, sample_metadata);
  } else {
    InsertFrame(frame, sample_time, sample_metadata);
  }
  prev_frame_ = frame;
}

void DelayVariationCalculator::InsertFirstFrame(const Frame& frame,
                                                Timestamp sample_time,
                                                MetadataT sample_metadata) {
  const auto s = [=](double sample_value) {
    return SamplesStatsCounter::StatsSample{.value = sample_value,
                                            .time = sample_time,
                                            .metadata = sample_metadata};
  };
  time_series_.rtp_timestamps.AddSample(
      s(static_cast<double>(frame.rtp_timestamp)));
  time_series_.arrival_times_ms.AddSample(s(frame.arrival_time.ms<double>()));
  time_series_.sizes_bytes.AddSample(s(frame.size.bytes<double>()));
  time_series_.inter_departure_times_ms.AddSample(s(0.0));
  time_series_.inter_arrival_times_ms.AddSample(s(0.0));
  time_series_.inter_delay_variations_ms.AddSample(s(0.0));
  time_series_.inter_size_variations_bytes.AddSample(s(0.0));
}

void DelayVariationCalculator::InsertFrame(const Frame& frame,
                                           Timestamp sample_time,
                                           MetadataT sample_metadata) {
  int64_t inter_rtp_time =
      frame.unwrapped_rtp_timestamp - prev_frame_->unwrapped_rtp_timestamp;
  TimeDelta inter_departure_time = inter_rtp_time / k90000Hz;
  TimeDelta inter_arrival_time = frame.arrival_time - prev_frame_->arrival_time;
  TimeDelta inter_delay_variation = inter_arrival_time - inter_departure_time;
  double inter_size_variation_bytes =
      frame.size.bytes<double>() - prev_frame_->size.bytes<double>();
  const auto s = [=](double sample_value) {
    return SamplesStatsCounter::StatsSample{.value = sample_value,
                                            .time = sample_time,
                                            .metadata = sample_metadata};
  };
  const auto ms = [](const TimeDelta& td) { return td.ms<double>(); };
  time_series_.rtp_timestamps.AddSample(
      s(static_cast<double>(frame.rtp_timestamp)));
  time_series_.arrival_times_ms.AddSample(s(frame.arrival_time.ms<double>()));
  time_series_.sizes_bytes.AddSample(s(frame.size.bytes<double>()));
  time_series_.inter_departure_times_ms.AddSample(s(ms(inter_departure_time)));
  time_series_.inter_arrival_times_ms.AddSample(s(ms(inter_arrival_time)));
  time_series_.inter_delay_variations_ms.AddSample(
      s(ms(inter_delay_variation)));
  time_series_.inter_size_variations_bytes.AddSample(
      s(inter_size_variation_bytes));
}

DelayVariationCalculator::MetadataT DelayVariationCalculator::BuildMetadata(
    const Frame& frame) {
  MetadataT metadata;
  if (prev_frame_) {
    if (prev_frame_->spatial_layer) {
      metadata["sl_prev"] = std::to_string(*prev_frame_->spatial_layer);
    }
    if (prev_frame_->temporal_layer) {
      metadata["tl_prev"] = std::to_string(*prev_frame_->temporal_layer);
    }
    if (prev_frame_->frame_type) {
      metadata["frame_type_prev"] =
          VideoFrameTypeToString(*prev_frame_->frame_type);
    }
  }
  if (frame.spatial_layer) {
    metadata["sl"] = std::to_string(*frame.spatial_layer);
  }
  if (frame.temporal_layer) {
    metadata["tl"] = std::to_string(*frame.temporal_layer);
  }
  if (frame.frame_type) {
    metadata["frame_type"] = VideoFrameTypeToString(*frame.frame_type);
  }
  return metadata;
}

}  // namespace test
}  // namespace webrtc
