/*
 *  Copyright (c) 2015 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 "webrtc/modules/remote_bitrate_estimator/test/packet_receiver.h"

#include <vector>

#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_framework.h"
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
#include "webrtc/system_wrappers/include/clock.h"
#include "webrtc/test/gtest.h"

namespace webrtc {
namespace testing {
namespace bwe {

PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
                               int flow_id,
                               BandwidthEstimatorType bwe_type,
                               bool plot_delay,
                               bool plot_bwe,
                               MetricRecorder* metric_recorder)
    : PacketProcessor(listener, flow_id, kReceiver),
      bwe_receiver_(CreateBweReceiver(bwe_type, flow_id, plot_bwe)),
      metric_recorder_(metric_recorder),
      plot_delay_(plot_delay),
      last_delay_plot_ms_(0),
      // #2 aligns the plot with the right axis.
      delay_prefix_("Delay_ms#2"),
      bwe_type_(bwe_type) {
  if (metric_recorder_ != nullptr) {
    // Setup the prefix std::strings used when logging.
    std::vector<std::string> prefixes;

    // Metric recorder plots them in separated figures,
    // alignment will take place with the #1 left axis.
    prefixes.push_back("MetricRecorderThroughput_kbps#1");
    prefixes.push_back("Sending_Estimate_kbps#1");
    prefixes.push_back("Delay_ms_#1");
    prefixes.push_back("Packet_Loss_#1");
    prefixes.push_back("Objective_function_#1");

    // Plot Total/PerFlow Available capacity together with throughputs.
    prefixes.push_back("Capacity_kbps#1");         // Total Available.
    prefixes.push_back("PerFlowCapacity_kbps#1");  // Available per flow.

    bool plot_loss = plot_delay;  // Plot loss if delay is plotted.
    metric_recorder_->SetPlotInformation(prefixes, plot_delay, plot_loss);
  }
}

PacketReceiver::PacketReceiver(PacketProcessorListener* listener,
                               int flow_id,
                               BandwidthEstimatorType bwe_type,
                               bool plot_delay,
                               bool plot_bwe)
    : PacketReceiver(listener,
                     flow_id,
                     bwe_type,
                     plot_delay,
                     plot_bwe,
                     nullptr) {
}

PacketReceiver::~PacketReceiver() {
}

void PacketReceiver::RunFor(int64_t time_ms, Packets* in_out) {
  Packets feedback;
  for (auto it = in_out->begin(); it != in_out->end();) {
    // PacketReceivers are only associated with a single stream, and therefore
    // should only process a single flow id.
    // TODO(holmer): Break this out into a Demuxer which implements both
    // PacketProcessorListener and PacketProcessor.
    BWE_TEST_LOGGING_CONTEXT("Receiver");
    if ((*it)->GetPacketType() == Packet::kMedia &&
        (*it)->flow_id() == *flow_ids().begin()) {
      BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin());
      const MediaPacket* media_packet = static_cast<const MediaPacket*>(*it);
      // We're treating the send time (from previous filter) as the arrival
      // time once packet reaches the estimator.
      int64_t arrival_time_ms = media_packet->send_time_ms();
      int64_t send_time_ms = media_packet->creation_time_ms();
      delay_stats_.Push(arrival_time_ms - send_time_ms);

      if (metric_recorder_ != nullptr) {
        metric_recorder_->UpdateTimeMs(arrival_time_ms);
        UpdateMetrics(arrival_time_ms, send_time_ms,
                      media_packet->payload_size());
        metric_recorder_->PlotAllDynamics();
      } else if (plot_delay_) {
        PlotDelay(arrival_time_ms, send_time_ms);
      }

      bwe_receiver_->ReceivePacket(arrival_time_ms, *media_packet);
      FeedbackPacket* fb = bwe_receiver_->GetFeedback(arrival_time_ms);
      if (fb)
        feedback.push_back(fb);
      delete media_packet;
      it = in_out->erase(it);
    } else {
      ++it;
    }
  }
  // Insert feedback packets to be sent back to the sender.
  in_out->merge(feedback, DereferencingComparator<Packet>);
}

void PacketReceiver::UpdateMetrics(int64_t arrival_time_ms,
                                   int64_t send_time_ms,
                                   size_t payload_size) {
  metric_recorder_->UpdateThroughput(bwe_receiver_->RecentKbps(), payload_size);
  metric_recorder_->UpdateDelayMs(arrival_time_ms - send_time_ms);
  metric_recorder_->UpdateLoss(bwe_receiver_->RecentPacketLossRatio());
  metric_recorder_->UpdateObjective();
}

void PacketReceiver::PlotDelay(int64_t arrival_time_ms, int64_t send_time_ms) {
  const int64_t kDelayPlotIntervalMs = 100;
  if (arrival_time_ms >= last_delay_plot_ms_ + kDelayPlotIntervalMs) {
    BWE_TEST_LOGGING_PLOT_WITH_NAME(0, delay_prefix_, arrival_time_ms,
                                    arrival_time_ms - send_time_ms,
                                    bwe_names[bwe_type_]);
    last_delay_plot_ms_ = arrival_time_ms;
  }
}

float PacketReceiver::GlobalPacketLoss() {
  return bwe_receiver_->GlobalReceiverPacketLossRatio();
}

Stats<double> PacketReceiver::GetDelayStats() const {
  return delay_stats_;
}
}  // namespace bwe
}  // namespace testing
}  // namespace webrtc
