/*
 *  Copyright (c) 2014 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 <stdio.h>

#include <memory>

#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/remote_bitrate_estimator/tools/bwe_rtp.h"
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
#include "rtc_base/format_macros.h"
#include "test/rtp_file_reader.h"

class Observer : public webrtc::RemoteBitrateObserver {
 public:
  explicit Observer(webrtc::Clock* clock) : clock_(clock) {}

  // Called when a receive channel group has a new bitrate estimate for the
  // incoming streams.
  virtual void OnReceiveBitrateChanged(const std::vector<uint32_t>& ssrcs,
                                       uint32_t bitrate) {
    printf("[%u] Num SSRCs: %d, bitrate: %u\n",
           static_cast<uint32_t>(clock_->TimeInMilliseconds()),
           static_cast<int>(ssrcs.size()), bitrate);
  }

  virtual ~Observer() {}

 private:
  webrtc::Clock* clock_;
};

int main(int argc, char* argv[]) {
  webrtc::test::RtpFileReader* reader;
  webrtc::RemoteBitrateEstimator* estimator;
  webrtc::RtpHeaderParser* parser;
  std::string estimator_used;
  webrtc::SimulatedClock clock(0);
  Observer observer(&clock);
  if (!ParseArgsAndSetupEstimator(argc, argv, &clock, &observer, &reader,
                                  &parser, &estimator, &estimator_used)) {
    return -1;
  }
  std::unique_ptr<webrtc::test::RtpFileReader> rtp_reader(reader);
  std::unique_ptr<webrtc::RtpHeaderParser> rtp_parser(parser);
  std::unique_ptr<webrtc::RemoteBitrateEstimator> rbe(estimator);

  // Process the file.
  int packet_counter = 0;
  int64_t next_rtp_time_ms = 0;
  int64_t first_rtp_time_ms = -1;
  int abs_send_time_count = 0;
  int ts_offset_count = 0;
  webrtc::test::RtpPacket packet;
  if (!rtp_reader->NextPacket(&packet)) {
    printf("No RTP packet found\n");
    return 0;
  }
  first_rtp_time_ms = packet.time_ms;
  packet.time_ms = packet.time_ms - first_rtp_time_ms;
  while (true) {
    if (next_rtp_time_ms <= clock.TimeInMilliseconds()) {
      if (!parser->IsRtcp(packet.data, packet.length)) {
        webrtc::RTPHeader header;
        parser->Parse(packet.data, packet.length, &header);
        if (header.extension.hasAbsoluteSendTime)
          ++abs_send_time_count;
        if (header.extension.hasTransmissionTimeOffset)
          ++ts_offset_count;
        size_t packet_length = packet.length;
        // Some RTP dumps only include the header, in which case packet.length
        // is equal to the header length. In those cases packet.original_length
        // usually contains the original packet length.
        if (packet.original_length > 0) {
          packet_length = packet.original_length;
        }
        rbe->IncomingPacket(clock.TimeInMilliseconds(),
                            packet_length - header.headerLength, header);
        ++packet_counter;
      }
      if (!rtp_reader->NextPacket(&packet)) {
        break;
      }
      packet.time_ms = packet.time_ms - first_rtp_time_ms;
      next_rtp_time_ms = packet.time_ms;
    }
    int64_t time_until_process_ms = rbe->TimeUntilNextProcess();
    if (time_until_process_ms <= 0) {
      rbe->Process();
    }
    int64_t time_until_next_event =
        std::min(rbe->TimeUntilNextProcess(),
                 next_rtp_time_ms - clock.TimeInMilliseconds());
    clock.AdvanceTimeMilliseconds(std::max<int64_t>(time_until_next_event, 0));
  }
  printf("Parsed %d packets\nTime passed: %" PRId64 " ms\n", packet_counter,
         clock.TimeInMilliseconds());
  printf("Estimator used: %s\n", estimator_used.c_str());
  printf("Packets with absolute send time: %d\n", abs_send_time_count);
  printf("Packets with timestamp offset: %d\n", ts_offset_count);
  printf("Packets with no extension: %d\n",
         packet_counter - ts_offset_count - abs_send_time_count);
  return 0;
}
