/*
 *  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 "modules/audio_coding/neteq/tools/rtc_event_log_source.h"

#include <assert.h>
#include <string.h>
#include <iostream>
#include <limits>

#include "modules/audio_coding/neteq/tools/packet.h"
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
#include "rtc_base/checks.h"

namespace webrtc {
namespace test {

RtcEventLogSource* RtcEventLogSource::Create(const std::string& file_name) {
  RtcEventLogSource* source = new RtcEventLogSource();
  RTC_CHECK(source->OpenFile(file_name));
  return source;
}

RtcEventLogSource::~RtcEventLogSource() {}

bool RtcEventLogSource::RegisterRtpHeaderExtension(RTPExtensionType type,
                                                   uint8_t id) {
  RTC_CHECK(parser_.get());
  return parser_->RegisterRtpHeaderExtension(type, id);
}

std::unique_ptr<Packet> RtcEventLogSource::NextPacket() {
  for (; rtp_packet_index_ < parsed_stream_.GetNumberOfEvents();
       rtp_packet_index_++) {
    if (parsed_stream_.GetEventType(rtp_packet_index_) ==
        ParsedRtcEventLog::RTP_EVENT) {
      PacketDirection direction;
      size_t header_length;
      size_t packet_length;
      uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_);
      parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, nullptr,
                                  &header_length, &packet_length, nullptr);

      if (direction != kIncomingPacket) {
        continue;
      }

      uint8_t* packet_header = new uint8_t[header_length];
      parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, packet_header,
                                  nullptr, nullptr, nullptr);
      std::unique_ptr<Packet> packet(
          new Packet(packet_header, header_length, packet_length,
                     static_cast<double>(timestamp_us) / 1000, *parser_.get()));

      if (!packet->valid_header()) {
        std::cout << "Warning: Packet with index " << rtp_packet_index_
                  << " has an invalid header and will be ignored." << std::endl;
        continue;
      }

      if (parsed_stream_.GetMediaType(packet->header().ssrc, direction) !=
          webrtc::ParsedRtcEventLog::MediaType::AUDIO) {
        continue;
      }

      // Check if the packet should not be filtered out.
      if (!filter_.test(packet->header().payloadType) &&
          !(use_ssrc_filter_ && packet->header().ssrc != ssrc_)) {
        ++rtp_packet_index_;
        return packet;
      }
    }
  }
  return nullptr;
}

int64_t RtcEventLogSource::NextAudioOutputEventMs() {
  while (audio_output_index_ < parsed_stream_.GetNumberOfEvents()) {
    if (parsed_stream_.GetEventType(audio_output_index_) ==
        ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT) {
      uint64_t timestamp_us = parsed_stream_.GetTimestamp(audio_output_index_);
      // We call GetAudioPlayout only to check that the protobuf event is
      // well-formed.
      parsed_stream_.GetAudioPlayout(audio_output_index_, nullptr);
      audio_output_index_++;
      return timestamp_us / 1000;
    }
    audio_output_index_++;
  }
  return std::numeric_limits<int64_t>::max();
}

RtcEventLogSource::RtcEventLogSource()
    : PacketSource(), parser_(RtpHeaderParser::Create()) {}

bool RtcEventLogSource::OpenFile(const std::string& file_name) {
  return parsed_stream_.ParseFile(file_name);
}

}  // namespace test
}  // namespace webrtc
