/*
 *  Copyright (c) 2011 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 "rtp_dump_impl.h"

#include <cassert>
#include <stdio.h>

#include "critical_section_wrapper.h"
#include "trace.h"

#if defined(_WIN32)
#include <Windows.h>
#include <mmsystem.h>
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
#include <string.h>
#include <sys/time.h>
#include <time.h>
#endif

#if (defined(_DEBUG) && defined(_WIN32))
#define DEBUG_PRINT(expr)   OutputDebugString(##expr)
#define DEBUG_PRINTP(expr, p)   \
{                               \
    char msg[128];              \
    sprintf(msg, ##expr, p);    \
    OutputDebugString(msg);     \
}
#else
#define DEBUG_PRINT(expr)    ((void)0)
#define DEBUG_PRINTP(expr,p) ((void)0)
#endif  // defined(_DEBUG) && defined(_WIN32)

namespace webrtc {
const WebRtc_Word8* RTPFILE_VERSION = "1.0";
const WebRtc_UWord32 MAX_UWORD32 = 0xffffffff;

// This stucture is specified in the rtpdump documentation.
// This struct corresponds to RD_packet_t in
// http://www.cs.columbia.edu/irt/software/rtptools/
typedef struct
{
    // Length of packet, including this header (may be smaller than plen if not
    // whole packet recorded).
    WebRtc_UWord16 length;
    // Actual header+payload length for RTP, 0 for RTCP.
    WebRtc_UWord16 plen;
    // Milliseconds since the start of recording.
    WebRtc_UWord32 offset;
} rtpDumpPktHdr_t;

RtpDump* RtpDump::CreateRtpDump()
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "CreateRtpDump()");
    return new RtpDumpImpl();
}

void RtpDump::DestroyRtpDump(RtpDump* object)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "DestroyRtpDump()");
    delete object;
}

RtpDumpImpl::RtpDumpImpl()
    : _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
      _file(*FileWrapper::Create()),
      _startTime(0)
{
    WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s created", __FUNCTION__);
}

RtpDump::~RtpDump()
{
}

RtpDumpImpl::~RtpDumpImpl()
{
    _file.Flush();
    _file.CloseFile();
    delete &_file;
    delete &_critSect;
    WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s deleted", __FUNCTION__);
}

WebRtc_Word32 RtpDumpImpl::Start(const WebRtc_Word8* fileNameUTF8)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "Start()");

    if (fileNameUTF8 == NULL)
    {
        return -1;
    }

    CriticalSectionScoped lock(_critSect);
    _file.Flush();
    _file.CloseFile();
    if (_file.OpenFile(fileNameUTF8, false, false, false) == -1)
    {
        WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
                     "failed to open the specified file");
        return -1;
    }

    // Store start of RTP dump (to be used for offset calculation later).
    _startTime = GetTimeInMS();

    // All rtp dump files start with #!rtpplay.
    WebRtc_Word8 magic[16];
    sprintf(magic, "#!rtpplay%s \n", RTPFILE_VERSION);
    _file.WriteText(magic);

    // The header according to the rtpdump documentation is sizeof(RD_hdr_t)
    // which is 8 + 4 + 2 = 14 bytes for 32-bit architecture (and 22 bytes on
    // 64-bit architecture). However, Wireshark use 16 bytes for the header
    // regardless of if the binary is 32-bit or 64-bit. Go by the same approach
    // as Wireshark since it makes more sense.
    // http://wiki.wireshark.org/rtpdump explains that an additional 2 bytes
    // of padding should be added to the header.
    WebRtc_Word8 dummyHdr[16];
    memset(dummyHdr, 0, 16);
    _file.Write(dummyHdr, sizeof(dummyHdr));
    return 0;
}

WebRtc_Word32 RtpDumpImpl::Stop()
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "Stop()");
    CriticalSectionScoped lock(_critSect);
    _file.Flush();
    _file.CloseFile();
    return 0;
}

bool RtpDumpImpl::IsActive() const
{
    CriticalSectionScoped lock(_critSect);
    return _file.Open();
}

WebRtc_Word32 RtpDumpImpl::DumpPacket(const WebRtc_UWord8* packet,
                                      WebRtc_UWord16 packetLength)
{
    CriticalSectionScoped lock(_critSect);
    if (!IsActive())
    {
        return 0;
    }

    if (packet == NULL)
    {
        return -1;
    }

    if (packetLength < 1)
    {
        return -1;
    }

    // If the packet doesn't contain a valid RTCP header the packet will be
    // considered RTP (without further verification).
    bool isRTCP = RTCP(packet);

    rtpDumpPktHdr_t hdr;
    WebRtc_UWord32 offset;

    // Offset is relative to when recording was started.
    offset = GetTimeInMS();
    if (offset < _startTime)
    {
        // Compensate for wraparound.
        offset += MAX_UWORD32 - _startTime + 1;
    } else {
        offset -= _startTime;
    }
    hdr.offset = RtpDumpHtonl(offset);

    hdr.length = RtpDumpHtons((WebRtc_UWord16)(packetLength + sizeof(hdr)));
    if (isRTCP)
    {
        hdr.plen = 0;
    }
    else
    {
        hdr.plen = RtpDumpHtons((WebRtc_UWord16)packetLength);
    }
    _file.Write(&hdr, sizeof(hdr));
    _file.Write(packet, packetLength);
    return 0;
}

bool RtpDumpImpl::RTCP(const WebRtc_UWord8* packet) const
{
    const WebRtc_UWord8 payloadType = packet[1];
    bool is_rtcp = false;

    switch(payloadType)
    {
    case 192:
        is_rtcp = true;
        break;
    case 193: case 195:
        break;
    case 200: case 201: case 202: case 203:
    case 204: case 205: case 206: case 207:
        is_rtcp = true;
        break;
    }
    return is_rtcp;
}

// TODO (hellner): why is TickUtil not used here?
inline WebRtc_UWord32 RtpDumpImpl::GetTimeInMS() const
{
#if defined(_WIN32)
    return timeGetTime();
#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
    struct timeval tv;
    struct timezone tz;
    unsigned long val;

    gettimeofday(&tv, &tz);
    val = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    return val;
#else
    #error Either _WIN32 or LINUX or WEBRTC_MAC has to be defined!
    assert(false);
    return 0;
#endif
}

inline WebRtc_UWord32 RtpDumpImpl::RtpDumpHtonl(WebRtc_UWord32 x) const
{
#if defined(WEBRTC_BIG_ENDIAN)
    return x;
#elif defined(WEBRTC_LITTLE_ENDIAN)
    return (x >> 24) + ((((x >> 16) & 0xFF) << 8) + ((((x >> 8) & 0xFF) << 16) +
                                                     ((x & 0xFF) << 24)));
#else
#error Either WEBRTC_BIG_ENDIAN or WEBRTC_LITTLE_ENDIAN has to be defined!
    assert(false);
    return 0;
#endif
}

inline WebRtc_UWord16 RtpDumpImpl::RtpDumpHtons(WebRtc_UWord16 x) const
{
#if defined(WEBRTC_BIG_ENDIAN)
    return x;
#elif defined(WEBRTC_LITTLE_ENDIAN)
    return (x >> 8) + ((x & 0xFF) << 8);
#else
    #error Either WEBRTC_BIG_ENDIAN or WEBRTC_LITTLE_ENDIAN has to be defined!
    assert(false);
    return 0;
#endif
}
} // namespace webrtc
