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

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <memory>
#include <optional>

#include "absl/strings/string_view.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/neteq/tools/packet_source.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h"
#include "test/rtp_file_reader.h"

namespace webrtc {
namespace test {

RtpFileSource* RtpFileSource::Create(absl::string_view file_name,
                                     std::optional<uint32_t> ssrc_filter) {
  RtpFileSource* source = new RtpFileSource(ssrc_filter);
  RTC_CHECK(source->OpenFile(file_name));
  return source;
}

bool RtpFileSource::ValidRtpDump(absl::string_view file_name) {
  std::unique_ptr<RtpFileReader> temp_file(
      RtpFileReader::Create(RtpFileReader::kRtpDump, file_name));
  return !!temp_file;
}

bool RtpFileSource::ValidPcap(absl::string_view file_name) {
  std::unique_ptr<RtpFileReader> temp_file(
      RtpFileReader::Create(RtpFileReader::kPcap, file_name));
  return !!temp_file;
}

RtpFileSource::~RtpFileSource() {}

bool RtpFileSource::RegisterRtpHeaderExtension(RTPExtensionType type,
                                               uint8_t id) {
  return rtp_header_extension_map_.RegisterByType(id, type);
}

std::unique_ptr<RtpPacketReceived> RtpFileSource::NextPacket() {
  while (true) {
    RtpPacket temp_packet;
    if (!rtp_reader_->NextPacket(&temp_packet)) {
      return nullptr;
    }
    if (temp_packet.original_length == 0) {
      // May be an RTCP packet.
      // Read the next one.
      continue;
    }
    auto rtp_packet =
        std::make_unique<RtpPacketReceived>(&rtp_header_extension_map_);
    if (!rtp_packet->Parse(temp_packet.data, temp_packet.length)) {
      continue;
    }
    if (filter_.test(rtp_packet->PayloadType()) ||
        (ssrc_filter_ && rtp_packet->Ssrc() != *ssrc_filter_)) {
      // This payload type should be filtered out. Continue to the next packet.
      continue;
    }
    rtp_packet->set_arrival_time(Timestamp::Millis(temp_packet.time_ms));

    // Simulate payload if only the RTP header was written in the file.
    if (temp_packet.original_length > rtp_packet->size()) {
      size_t payload_size =
          temp_packet.original_length - rtp_packet->headers_size();
      if (rtp_packet->has_padding()) {
        // If padding bit is set in the RTP header, assume it was a pure padding
        // packet.
        rtp_packet->SetPadding(payload_size);
      } else {
        std::fill_n(rtp_packet->AllocatePayload(payload_size), payload_size, 0);
      }
    }
    return rtp_packet;
  }
}

RtpFileSource::RtpFileSource(std::optional<uint32_t> ssrc_filter)
    : PacketSource(), ssrc_filter_(ssrc_filter) {}

bool RtpFileSource::OpenFile(absl::string_view file_name) {
  rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kRtpDump, file_name));
  if (rtp_reader_)
    return true;
  rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kPcap, file_name));
  if (!rtp_reader_) {
    RTC_FATAL()
        << "Couldn't open input file as either a rtpdump or .pcap. Note "
        << "that .pcapng is not supported.";
  }
  return true;
}

}  // namespace test
}  // namespace webrtc
