/*
 *  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 <stdint.h>
#include <string.h>

#include <iostream>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/flags/usage.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/rtp_headers.h"
#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "logging/rtc_event_log/rtc_event_processor.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_to_number.h"
#include "test/rtp_file_reader.h"
#include "test/rtp_file_writer.h"

ABSL_FLAG(
    bool,
    audio,
    true,
    "Use --noaudio to exclude audio packets from the converted RTPdump file.");
ABSL_FLAG(
    bool,
    video,
    true,
    "Use --novideo to exclude video packets from the converted RTPdump file.");
ABSL_FLAG(
    bool,
    data,
    true,
    "Use --nodata to exclude data packets from the converted RTPdump file.");
ABSL_FLAG(
    bool,
    rtp,
    true,
    "Use --nortp to exclude RTP packets from the converted RTPdump file.");
ABSL_FLAG(
    bool,
    rtcp,
    true,
    "Use --nortcp to exclude RTCP packets from the converted RTPdump file.");
ABSL_FLAG(std::string,
          ssrc,
          "",
          "Store only packets with this SSRC (decimal or hex, the latter "
          "starting with 0x).");

namespace {

using MediaType = webrtc::ParsedRtcEventLog::MediaType;

// Parses the input string for a valid SSRC. If a valid SSRC is found, it is
// written to the output variable `ssrc`, and true is returned. Otherwise,
// false is returned.
// The empty string must be validated as true, because it is the default value
// of the command-line flag. In this case, no value is written to the output
// variable.
std::optional<uint32_t> ParseSsrc(absl::string_view str) {
  // Set `base` to 0 to allow detection of the "0x" prefix in case hex is used.
  return rtc::StringToNumber<uint32_t>(str, 0);
}

bool ShouldSkipStream(MediaType media_type,
                      uint32_t ssrc,
                      std::optional<uint32_t> ssrc_filter) {
  if (!absl::GetFlag(FLAGS_audio) && media_type == MediaType::AUDIO)
    return true;
  if (!absl::GetFlag(FLAGS_video) && media_type == MediaType::VIDEO)
    return true;
  if (!absl::GetFlag(FLAGS_data) && media_type == MediaType::DATA)
    return true;
  if (ssrc_filter.has_value() && ssrc != *ssrc_filter)
    return true;
  return false;
}

// Convert a LoggedRtpPacketIncoming to a test::RtpPacket. Header extension IDs
// are allocated according to the provided extension map. This might not match
// the extension map used in the actual call.
void ConvertRtpPacket(
    const webrtc::LoggedRtpPacketIncoming& incoming,
    const webrtc::RtpHeaderExtensionMap& default_extension_map,
    webrtc::test::RtpPacket* packet) {
  webrtc::RtpPacket reconstructed_packet(&default_extension_map);

  reconstructed_packet.SetMarker(incoming.rtp.header.markerBit);
  reconstructed_packet.SetPayloadType(incoming.rtp.header.payloadType);
  reconstructed_packet.SetSequenceNumber(incoming.rtp.header.sequenceNumber);
  reconstructed_packet.SetTimestamp(incoming.rtp.header.timestamp);
  reconstructed_packet.SetSsrc(incoming.rtp.header.ssrc);
  if (incoming.rtp.header.numCSRCs > 0) {
    reconstructed_packet.SetCsrcs(rtc::ArrayView<const uint32_t>(
        incoming.rtp.header.arrOfCSRCs, incoming.rtp.header.numCSRCs));
  }

  // Set extensions.
  if (incoming.rtp.header.extension.hasTransmissionTimeOffset)
    reconstructed_packet.SetExtension<webrtc::TransmissionOffset>(
        incoming.rtp.header.extension.transmissionTimeOffset);
  if (incoming.rtp.header.extension.hasAbsoluteSendTime)
    reconstructed_packet.SetExtension<webrtc::AbsoluteSendTime>(
        incoming.rtp.header.extension.absoluteSendTime);
  if (incoming.rtp.header.extension.hasTransportSequenceNumber)
    reconstructed_packet.SetExtension<webrtc::TransportSequenceNumber>(
        incoming.rtp.header.extension.transportSequenceNumber);
  if (incoming.rtp.header.extension.audio_level())
    reconstructed_packet.SetExtension<webrtc::AudioLevelExtension>(
        *incoming.rtp.header.extension.audio_level());
  if (incoming.rtp.header.extension.hasVideoRotation)
    reconstructed_packet.SetExtension<webrtc::VideoOrientation>(
        incoming.rtp.header.extension.videoRotation);
  if (incoming.rtp.header.extension.hasVideoContentType)
    reconstructed_packet.SetExtension<webrtc::VideoContentTypeExtension>(
        incoming.rtp.header.extension.videoContentType);
  if (incoming.rtp.header.extension.has_video_timing)
    reconstructed_packet.SetExtension<webrtc::VideoTimingExtension>(
        incoming.rtp.header.extension.video_timing);

  RTC_DCHECK_EQ(reconstructed_packet.size(), incoming.rtp.header_length);
  RTC_DCHECK_EQ(reconstructed_packet.headers_size(),
                incoming.rtp.header_length);
  memcpy(packet->data, reconstructed_packet.data(),
         reconstructed_packet.headers_size());
  packet->length = reconstructed_packet.headers_size();
  packet->original_length = incoming.rtp.total_length;
  packet->time_ms = incoming.log_time_ms();
  // Set padding bit.
  if (incoming.rtp.header.paddingLength > 0)
    packet->data[0] = packet->data[0] | 0x20;
}

}  // namespace

// This utility will convert a stored event log to the rtpdump format.
int main(int argc, char* argv[]) {
  absl::SetProgramUsageMessage(
      "Tool for converting an RtcEventLog file to an "
      "RTP dump file.\n"
      "Example usage:\n"
      "./rtc_event_log2rtp_dump input.rel output.rtp\n");
  std::vector<char*> args = absl::ParseCommandLine(argc, argv);
  if (args.size() != 3) {
    std::cout << absl::ProgramUsageMessage();
    return 1;
  }

  std::string input_file = args[1];
  std::string output_file = args[2];

  std::optional<uint32_t> ssrc_filter;
  if (!absl::GetFlag(FLAGS_ssrc).empty()) {
    ssrc_filter = ParseSsrc(absl::GetFlag(FLAGS_ssrc));
    RTC_CHECK(ssrc_filter.has_value()) << "Failed to read SSRC filter flag.";
  }

  webrtc::ParsedRtcEventLog parsed_stream;
  auto status = parsed_stream.ParseFile(input_file);
  if (!status.ok()) {
    std::cerr << "Failed to parse event log " << input_file << ": "
              << status.message() << std::endl;
    return -1;
  }

  std::unique_ptr<webrtc::test::RtpFileWriter> rtp_writer(
      webrtc::test::RtpFileWriter::Create(
          webrtc::test::RtpFileWriter::FileFormat::kRtpDump, output_file));

  if (!rtp_writer) {
    std::cerr << "Error while opening output file: " << output_file
              << std::endl;
    return -1;
  }

  int rtp_counter = 0, rtcp_counter = 0;
  bool header_only = false;

  webrtc::RtpHeaderExtensionMap default_extension_map =
      webrtc::ParsedRtcEventLog::GetDefaultHeaderExtensionMap();
  auto handle_rtp = [&default_extension_map, &rtp_writer, &rtp_counter](
                        const webrtc::LoggedRtpPacketIncoming& incoming) {
    webrtc::test::RtpPacket packet;
    ConvertRtpPacket(incoming, default_extension_map, &packet);

    rtp_writer->WritePacket(&packet);
    rtp_counter++;
  };

  auto handle_rtcp = [&rtp_writer, &rtcp_counter](
                         const webrtc::LoggedRtcpPacketIncoming& incoming) {
    webrtc::test::RtpPacket packet;
    memcpy(packet.data, incoming.rtcp.raw_data.data(),
           incoming.rtcp.raw_data.size());
    packet.length = incoming.rtcp.raw_data.size();
    // For RTCP packets the original_length should be set to 0 in the
    // RTPdump format.
    packet.original_length = 0;
    packet.time_ms = incoming.log_time_ms();

    rtp_writer->WritePacket(&packet);
    rtcp_counter++;
  };

  webrtc::RtcEventProcessor event_processor;
  for (const auto& stream : parsed_stream.incoming_rtp_packets_by_ssrc()) {
    MediaType media_type =
        parsed_stream.GetMediaType(stream.ssrc, webrtc::kIncomingPacket);
    if (ShouldSkipStream(media_type, stream.ssrc, ssrc_filter))
      continue;
    event_processor.AddEvents(stream.incoming_packets, handle_rtp);
  }
  // Note that `packet_ssrc` is the sender SSRC. An RTCP message may contain
  // report blocks for many streams, thus several SSRCs and they don't
  // necessarily have to be of the same media type. We therefore don't
  // support filtering of RTCP based on SSRC and media type.
  event_processor.AddEvents(parsed_stream.incoming_rtcp_packets(), handle_rtcp);

  event_processor.ProcessEventsInOrder();

  std::cout << "Wrote " << rtp_counter << (header_only ? " header-only" : "")
            << " RTP packets and " << rtcp_counter
            << " RTCP packets to the "
               "output file."
            << std::endl;
  return 0;
}
