/*
 *  Copyright (c) 2012 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 <assert.h>
#include <stdio.h>
#include <vector>

#include "google/gflags.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"

// Flag validator.
static bool ValidatePayloadType(const char* flagname, int32_t value) {
  if (value >= 0 && value <= 127)  // Value is ok.
    return true;
  printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
  return false;
}
static bool ValidateExtensionId(const char* flagname, int32_t value) {
  if (value > 0 && value <= 255)  // Value is ok.
    return true;
  printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
  return false;
}

// Define command line flags.
DEFINE_int32(red, 117, "RTP payload type for RED");
static const bool red_dummy =
    google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType);
DEFINE_int32(audio_level, 1, "Extension ID for audio level (RFC 6464)");
static const bool audio_level_dummy =
    google::RegisterFlagValidator(&FLAGS_audio_level, &ValidateExtensionId);
DEFINE_int32(abs_send_time, 3, "Extension ID for absolute sender time");
static const bool abs_send_time_dummy =
    google::RegisterFlagValidator(&FLAGS_abs_send_time, &ValidateExtensionId);

int main(int argc, char* argv[]) {
  std::string program_name = argv[0];
  std::string usage =
      "Tool for parsing an RTP dump file to text output.\n"
      "Run " +
      program_name +
      " --helpshort for usage.\n"
      "Example usage:\n" +
      program_name + " input.rtp output.txt\n\n" +
      "Output is sent to stdout if no output file is given." +
      "Note that this tool can read files with our without payloads.";
  google::SetUsageMessage(usage);
  google::ParseCommandLineFlags(&argc, &argv, true);

  if (argc != 2 && argc != 3) {
    // Print usage information.
    printf("%s", google::ProgramUsage());
    return 0;
  }

  printf("Input file: %s\n", argv[1]);
  rtc::scoped_ptr<webrtc::test::RtpFileSource> file_source(
      webrtc::test::RtpFileSource::Create(argv[1]));
  assert(file_source.get());
  // Set RTP extension IDs.
  bool print_audio_level = false;
  if (!google::GetCommandLineFlagInfoOrDie("audio_level").is_default) {
    print_audio_level = true;
    file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel,
                                            FLAGS_audio_level);
  }
  bool print_abs_send_time = false;
  if (!google::GetCommandLineFlagInfoOrDie("abs_send_time").is_default) {
    print_abs_send_time = true;
    file_source->RegisterRtpHeaderExtension(
        webrtc::kRtpExtensionAbsoluteSendTime, FLAGS_abs_send_time);
  }

  FILE* out_file;
  if (argc == 3) {
    out_file = fopen(argv[2], "wt");
    if (!out_file) {
      printf("Cannot open output file %s\n", argv[2]);
      return -1;
    }
    printf("Output file: %s\n\n", argv[2]);
  } else {
    out_file = stdout;
  }

  // Print file header.
  fprintf(out_file, "SeqNo  TimeStamp   SendTime  Size    PT  M       SSRC");
  if (print_audio_level) {
    fprintf(out_file, " AuLvl (V)");
  }
  if (print_abs_send_time) {
    fprintf(out_file, " AbsSendTime");
  }
  fprintf(out_file, "\n");

  uint32_t max_abs_send_time = 0;
  int cycles = -1;
  rtc::scoped_ptr<webrtc::test::Packet> packet;
  while (true) {
    packet.reset(file_source->NextPacket());
    if (!packet.get()) {
      // End of file reached.
      break;
    }
    // Write packet data to file. Use virtual_packet_length_bytes so that the
    // correct packet sizes are printed also for RTP header-only dumps.
    fprintf(out_file,
            "%5u %10u %10u %5i %5i %2i %#08X",
            packet->header().sequenceNumber,
            packet->header().timestamp,
            static_cast<unsigned int>(packet->time_ms()),
            static_cast<int>(packet->virtual_packet_length_bytes()),
            packet->header().payloadType,
            packet->header().markerBit,
            packet->header().ssrc);
    if (print_audio_level && packet->header().extension.hasAudioLevel) {
      fprintf(out_file,
              " %5u (%1i)",
              packet->header().extension.audioLevel,
              packet->header().extension.voiceActivity);
    }
    if (print_abs_send_time && packet->header().extension.hasAbsoluteSendTime) {
      if (cycles == -1) {
        // Initialize.
        max_abs_send_time = packet->header().extension.absoluteSendTime;
        cycles = 0;
      }
      // Abs sender time is 24 bit 6.18 fixed point. Shift by 8 to normalize to
      // 32 bits (unsigned). Calculate the difference between this packet's
      // send time and the maximum observed. Cast to signed 32-bit to get the
      // desired wrap-around behavior.
      if (static_cast<int32_t>(
              (packet->header().extension.absoluteSendTime << 8) -
              (max_abs_send_time << 8)) >= 0) {
        // The difference is non-negative, meaning that this packet is newer
        // than the previously observed maximum absolute send time.
        if (packet->header().extension.absoluteSendTime < max_abs_send_time) {
          // Wrap detected.
          cycles++;
        }
        max_abs_send_time = packet->header().extension.absoluteSendTime;
      }
      // Abs sender time is 24 bit 6.18 fixed point. Divide by 2^18 to convert
      // to floating point representation.
      double send_time_seconds =
          static_cast<double>(packet->header().extension.absoluteSendTime) /
              262144 +
          64.0 * cycles;
      fprintf(out_file, " %11f", send_time_seconds);
    }
    fprintf(out_file, "\n");

    if (packet->header().payloadType == FLAGS_red) {
      std::list<webrtc::RTPHeader*> red_headers;
      packet->ExtractRedHeaders(&red_headers);
      while (!red_headers.empty()) {
        webrtc::RTPHeader* red = red_headers.front();
        assert(red);
        fprintf(out_file,
                "* %5u %10u %10u %5i\n",
                red->sequenceNumber,
                red->timestamp,
                static_cast<unsigned int>(packet->time_ms()),
                red->payloadType);
        red_headers.pop_front();
        delete red;
      }
    }
  }

  fclose(out_file);

  return 0;
}
