/*
 *  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 "RTPFile.h"

#include <sys/types.h>

#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <string>

#include "absl/strings/string_view.h"
#include "api/rtp_headers.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/synchronization/mutex.h"

#ifdef WIN32
#include <Winsock2.h>
#else
#endif

// TODO(tlegrand): Consider removing usage of gtest.
#include "test/gtest.h"

namespace webrtc {

void RTPStream::ParseRTPHeader(RTPHeader* rtp_header,
                               const uint8_t* rtpHeader) {
  rtp_header->payloadType = rtpHeader[1];
  rtp_header->sequenceNumber =
      (static_cast<uint16_t>(rtpHeader[2]) << 8) | rtpHeader[3];
  rtp_header->timestamp = (static_cast<uint32_t>(rtpHeader[4]) << 24) |
                          (static_cast<uint32_t>(rtpHeader[5]) << 16) |
                          (static_cast<uint32_t>(rtpHeader[6]) << 8) |
                          rtpHeader[7];
  rtp_header->ssrc = (static_cast<uint32_t>(rtpHeader[8]) << 24) |
                     (static_cast<uint32_t>(rtpHeader[9]) << 16) |
                     (static_cast<uint32_t>(rtpHeader[10]) << 8) |
                     rtpHeader[11];
}

void RTPStream::MakeRTPheader(uint8_t* rtpHeader,
                              uint8_t payloadType,
                              int16_t seqNo,
                              uint32_t timeStamp,
                              uint32_t ssrc) {
  rtpHeader[0] = 0x80;
  rtpHeader[1] = payloadType;
  rtpHeader[2] = (seqNo >> 8) & 0xFF;
  rtpHeader[3] = seqNo & 0xFF;
  rtpHeader[4] = timeStamp >> 24;
  rtpHeader[5] = (timeStamp >> 16) & 0xFF;
  rtpHeader[6] = (timeStamp >> 8) & 0xFF;
  rtpHeader[7] = timeStamp & 0xFF;
  rtpHeader[8] = ssrc >> 24;
  rtpHeader[9] = (ssrc >> 16) & 0xFF;
  rtpHeader[10] = (ssrc >> 8) & 0xFF;
  rtpHeader[11] = ssrc & 0xFF;
}

RTPPacket::RTPPacket(uint8_t payloadType,
                     uint32_t timeStamp,
                     int16_t seqNo,
                     const uint8_t* payloadData,
                     size_t payloadSize,
                     uint32_t frequency)
    : payloadType(payloadType),
      timeStamp(timeStamp),
      seqNo(seqNo),
      payloadSize(payloadSize),
      frequency(frequency) {
  if (payloadSize > 0) {
    this->payloadData = new uint8_t[payloadSize];
    memcpy(this->payloadData, payloadData, payloadSize);
  }
}

RTPPacket::~RTPPacket() {
  delete[] payloadData;
}

void RTPBuffer::Write(const uint8_t payloadType,
                      const uint32_t timeStamp,
                      const int16_t seqNo,
                      const uint8_t* payloadData,
                      const size_t payloadSize,
                      uint32_t frequency) {
  RTPPacket* packet = new RTPPacket(payloadType, timeStamp, seqNo, payloadData,
                                    payloadSize, frequency);
  MutexLock lock(&mutex_);
  _rtpQueue.push(packet);
}

size_t RTPBuffer::Read(RTPHeader* rtp_header,
                       uint8_t* payloadData,
                       size_t payloadSize,
                       uint32_t* offset) {
  RTPPacket* packet;
  {
    MutexLock lock(&mutex_);
    packet = _rtpQueue.front();
    _rtpQueue.pop();
  }
  rtp_header->markerBit = 1;
  rtp_header->payloadType = packet->payloadType;
  rtp_header->sequenceNumber = packet->seqNo;
  rtp_header->ssrc = 0;
  rtp_header->timestamp = packet->timeStamp;
  if (packet->payloadSize > 0 && payloadSize >= packet->payloadSize) {
    memcpy(payloadData, packet->payloadData, packet->payloadSize);
  } else {
    return 0;
  }
  *offset = (packet->timeStamp / (packet->frequency / 1000));

  return packet->payloadSize;
}

bool RTPBuffer::EndOfFile() const {
  MutexLock lock(&mutex_);
  return _rtpQueue.empty();
}

void RTPFile::Open(absl::string_view filename, absl::string_view mode) {
  std::string filename_str = std::string(filename);
  if ((_rtpFile = fopen(filename_str.c_str(), std::string(mode).c_str())) ==
      nullptr) {
    printf("Cannot write file %s.\n", filename_str.c_str());
    ADD_FAILURE() << "Unable to write file";
    exit(1);
  }
}

void RTPFile::Close() {
  if (_rtpFile != nullptr) {
    fclose(_rtpFile);
    _rtpFile = nullptr;
  }
}

void RTPFile::WriteHeader() {
  // Write data in a format that NetEQ and RTP Play can parse
  fprintf(_rtpFile, "#!RTPencode%s\n", "1.0");
  uint32_t dummy_variable = 0;
  // should be converted to network endian format, but does not matter when 0
  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile));
  fflush(_rtpFile);
}

void RTPFile::ReadHeader() {
  uint32_t start_sec, start_usec, source;
  uint16_t port, padding;
  char fileHeader[40];
  EXPECT_TRUE(fgets(fileHeader, 40, _rtpFile) != nullptr);
  EXPECT_EQ(1u, fread(&start_sec, 4, 1, _rtpFile));
  start_sec = ntohl(start_sec);
  EXPECT_EQ(1u, fread(&start_usec, 4, 1, _rtpFile));
  start_usec = ntohl(start_usec);
  EXPECT_EQ(1u, fread(&source, 4, 1, _rtpFile));
  source = ntohl(source);
  EXPECT_EQ(1u, fread(&port, 2, 1, _rtpFile));
  port = ntohs(port);
  EXPECT_EQ(1u, fread(&padding, 2, 1, _rtpFile));
  padding = ntohs(padding);
}

void RTPFile::Write(const uint8_t payloadType,
                    const uint32_t timeStamp,
                    const int16_t seqNo,
                    const uint8_t* payloadData,
                    const size_t payloadSize,
                    uint32_t frequency) {
  /* write RTP packet to file */
  uint8_t rtpHeader[12];
  MakeRTPheader(rtpHeader, payloadType, seqNo, timeStamp, 0);
  ASSERT_LE(12 + payloadSize + 8, std::numeric_limits<u_short>::max());
  uint16_t lengthBytes = htons(static_cast<u_short>(12 + payloadSize + 8));
  uint16_t plen = htons(static_cast<u_short>(12 + payloadSize));
  uint32_t offsetMs;

  offsetMs = (timeStamp / (frequency / 1000));
  offsetMs = htonl(offsetMs);
  EXPECT_EQ(1u, fwrite(&lengthBytes, 2, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&plen, 2, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&offsetMs, 4, 1, _rtpFile));
  EXPECT_EQ(1u, fwrite(&rtpHeader, 12, 1, _rtpFile));
  EXPECT_EQ(payloadSize, fwrite(payloadData, 1, payloadSize, _rtpFile));
}

size_t RTPFile::Read(RTPHeader* rtp_header,
                     uint8_t* payloadData,
                     size_t payloadSize,
                     uint32_t* offset) {
  uint16_t lengthBytes;
  uint16_t plen;
  uint8_t rtpHeader[12];
  size_t read_len = fread(&lengthBytes, 2, 1, _rtpFile);
  /* Check if we have reached end of file. */
  if ((read_len == 0) && feof(_rtpFile)) {
    _rtpEOF = true;
    return 0;
  }
  EXPECT_EQ(1u, fread(&plen, 2, 1, _rtpFile));
  EXPECT_EQ(1u, fread(offset, 4, 1, _rtpFile));
  lengthBytes = ntohs(lengthBytes);
  plen = ntohs(plen);
  *offset = ntohl(*offset);
  EXPECT_GT(plen, 11);

  EXPECT_EQ(1u, fread(rtpHeader, 12, 1, _rtpFile));
  ParseRTPHeader(rtp_header, rtpHeader);
  EXPECT_EQ(lengthBytes, plen + 8);

  if (plen == 0) {
    return 0;
  }
  if (lengthBytes < 20) {
    return 0;
  }
  if (payloadSize < static_cast<size_t>((lengthBytes - 20))) {
    return 0;
  }
  lengthBytes -= 20;
  EXPECT_EQ(lengthBytes, fread(payloadData, 1, lengthBytes, _rtpFile));
  return lengthBytes;
}

}  // namespace webrtc
