/*
 *  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 <iostream>

#include "audio_coding_module.h"
#include "Channel.h"
#include "tick_util.h"
#include "typedefs.h"
#include "common_types.h"

namespace webrtc {

WebRtc_Word32
Channel::SendData(
        const FrameType       frameType,
        const WebRtc_UWord8   payloadType,
        const WebRtc_UWord32  timeStamp,
        const WebRtc_UWord8*  payloadData,
        const WebRtc_UWord16  payloadSize,
        const RTPFragmentationHeader* fragmentation)
{
    WebRtcRTPHeader rtpInfo;
    WebRtc_Word32   status;
    WebRtc_UWord16  payloadDataSize = payloadSize;

    rtpInfo.header.markerBit = false;
    rtpInfo.header.ssrc = 0;
    rtpInfo.header.sequenceNumber = _seqNo++;
    rtpInfo.header.payloadType = payloadType;
    rtpInfo.header.timestamp = timeStamp;
    if(frameType == kAudioFrameCN)
    {
        rtpInfo.type.Audio.isCNG = true;
    }
    else
    {
        rtpInfo.type.Audio.isCNG = false;
    }
    if(frameType == kFrameEmpty)
    {
        // Skip this frame
        return 0;
    }

    rtpInfo.type.Audio.channel = 1;
    // Treat fragmentation separately
    if(fragmentation != NULL)
    {
        if((fragmentation->fragmentationTimeDiff[1] <= 0x3fff) && // silence for too long send only new data
            (fragmentation->fragmentationVectorSize == 2))
        {
            // only 0x80 if we have multiple blocks
            _payloadData[0] = 0x80 + fragmentation->fragmentationPlType[1];
            WebRtc_UWord32 REDheader =  (((WebRtc_UWord32)fragmentation->fragmentationTimeDiff[1]) << 10) + fragmentation->fragmentationLength[1];
            _payloadData[1] = WebRtc_UWord8((REDheader >> 16) & 0x000000FF);
            _payloadData[2] = WebRtc_UWord8((REDheader >> 8) & 0x000000FF);
            _payloadData[3] = WebRtc_UWord8(REDheader & 0x000000FF);

            _payloadData[4] = fragmentation->fragmentationPlType[0];
            // copy the RED data
            memcpy(_payloadData + 5,
                payloadData + fragmentation->fragmentationOffset[1],
                fragmentation->fragmentationLength[1]);
            // copy the normal data
            memcpy(_payloadData + 5 + fragmentation->fragmentationLength[1],
                payloadData + fragmentation->fragmentationOffset[0],
                fragmentation->fragmentationLength[0]);
            payloadDataSize += 5;
        } else
        {
            // single block (newest one)
            memcpy(_payloadData,
                payloadData + fragmentation->fragmentationOffset[0],
                fragmentation->fragmentationLength[0]);
            payloadDataSize = WebRtc_UWord16(fragmentation->fragmentationLength[0]);
            rtpInfo.header.payloadType = fragmentation->fragmentationPlType[0];
        }
    }
    else
    {
        memcpy(_payloadData, payloadData, payloadDataSize);
        if(_isStereo)
        {
            if(_leftChannel)
            {
                memcpy(&_rtpInfo, &rtpInfo, sizeof(WebRtcRTPHeader));
                _leftChannel = false;
                rtpInfo.type.Audio.channel = 1;
            }
            else
            {
                memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcRTPHeader));
                _leftChannel = true;
                rtpInfo.type.Audio.channel = 2;
            }
        }
    }

    _channelCritSect->Enter();
    if(_saveBitStream)
    {
        //fwrite(payloadData, sizeof(WebRtc_UWord8), payloadSize, _bitStreamFile);
    }

    if(!_isStereo)
    {
        CalcStatistics(rtpInfo, payloadSize);
    }
    _lastInTimestamp = timeStamp;
    _totalBytes += payloadDataSize;
    _channelCritSect->Leave();

    if(_useFECTestWithPacketLoss)
    {
        _packetLoss += 1;
        if(_packetLoss == 3)
        {
            _packetLoss = 0;
            return 0;
        }
    }

    status = _receiverACM->IncomingPacket(_payloadData, payloadDataSize,
                                          rtpInfo);

    return status;
}

void
Channel::CalcStatistics(
    WebRtcRTPHeader& rtpInfo,
    WebRtc_UWord16   payloadSize)
{
    int n;
    if((rtpInfo.header.payloadType != _lastPayloadType) &&
        (_lastPayloadType != -1))
    {
        // payload-type is changed.
        // we have to terminate the calculations on the previous payload type
        // we ignore the last packet in that payload type just to make things
        // easier.
        for(n = 0; n < MAX_NUM_PAYLOADS; n++)
        {
            if(_lastPayloadType == _payloadStats[n].payloadType)
            {
                _payloadStats[n].newPacket = true;
                break;
            }
        }
    }
    _lastPayloadType = rtpInfo.header.payloadType;

    bool newPayload = true;
    ACMTestPayloadStats* currentPayloadStr = NULL;
    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
    {
        if(rtpInfo.header.payloadType == _payloadStats[n].payloadType)
        {
            newPayload = false;
            currentPayloadStr = &_payloadStats[n];
            break;
        }
    }

    if(!newPayload)
    {
        if(!currentPayloadStr->newPacket)
        {
            WebRtc_UWord32 lastFrameSizeSample = (WebRtc_UWord32)((WebRtc_UWord32)rtpInfo.header.timestamp -
                (WebRtc_UWord32)currentPayloadStr->lastTimestamp);
            assert(lastFrameSizeSample > 0);
            int k = 0;
            while((currentPayloadStr->frameSizeStats[k].frameSizeSample !=
                lastFrameSizeSample) &&
                (currentPayloadStr->frameSizeStats[k].frameSizeSample != 0))
            {
                k++;
            }
            ACMTestFrameSizeStats* currentFrameSizeStats =
                &(currentPayloadStr->frameSizeStats[k]);
            currentFrameSizeStats->frameSizeSample = (WebRtc_Word16)lastFrameSizeSample;

            // increment the number of encoded samples.
            currentFrameSizeStats->totalEncodedSamples +=
                lastFrameSizeSample;
            // increment the number of recveived packets
            currentFrameSizeStats->numPackets++;
            // increment the total number of bytes (this is based on
            // the previous payload we don't know the frame-size of
            // the current payload.
            currentFrameSizeStats->totalPayloadLenByte +=
                currentPayloadStr->lastPayloadLenByte;
            // store the maximum payload-size (this is based on
            // the previous payload we don't know the frame-size of
            // the current payload.
            if(currentFrameSizeStats->maxPayloadLen <
                currentPayloadStr->lastPayloadLenByte)
            {
                currentFrameSizeStats->maxPayloadLen =
                    currentPayloadStr->lastPayloadLenByte;
            }
            // store the current values for the next time
            currentPayloadStr->lastTimestamp = rtpInfo.header.timestamp;
            currentPayloadStr->lastPayloadLenByte = payloadSize;
        }
        else
        {
            currentPayloadStr->newPacket          = false;
            currentPayloadStr->lastPayloadLenByte = payloadSize;
            currentPayloadStr->lastTimestamp      = rtpInfo.header.timestamp;
            currentPayloadStr->payloadType        = rtpInfo.header.payloadType;
        }
    }
    else
    {
        n = 0;
        while(_payloadStats[n].payloadType != -1)
        {
            n++;
        }
        // first packet
        _payloadStats[n].newPacket          = false;
        _payloadStats[n].lastPayloadLenByte = payloadSize;
        _payloadStats[n].lastTimestamp      = rtpInfo.header.timestamp;
        _payloadStats[n].payloadType        = rtpInfo.header.payloadType;
    }
}

Channel::Channel(WebRtc_Word16 chID) :
_receiverACM(NULL),
_seqNo(0),
_channelCritSect(CriticalSectionWrapper::CreateCriticalSection()),
_bitStreamFile(NULL),
_saveBitStream(false),
_lastPayloadType(-1),
_isStereo(false),
_leftChannel(true),
_lastInTimestamp(0),
_packetLoss(0),
_useFECTestWithPacketLoss(false),
_beginTime(TickTime::MillisecondTimestamp()),
_totalBytes(0)
{
    int n;
    int k;
    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
    {
        _payloadStats[n].payloadType = -1;
        _payloadStats[n].newPacket   = true;
        for(k = 0; k < MAX_NUM_FRAMESIZES; k++)
        {
            _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
            _payloadStats[n].frameSizeStats[k].maxPayloadLen   = 0;
            _payloadStats[n].frameSizeStats[k].numPackets      = 0;
            _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
            _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
        }
    }
    if(chID >= 0)
    {
        _saveBitStream = true;
        char bitStreamFileName[500];
        sprintf(bitStreamFileName, "bitStream_%d.dat", chID);
        _bitStreamFile = fopen(bitStreamFileName, "wb");
    }
    else
    {
        _saveBitStream = false;
    }
}

Channel::~Channel()
{
    delete _channelCritSect;
}

void
Channel::RegisterReceiverACM(AudioCodingModule* acm)
{
    _receiverACM = acm;
    return;
}

void
Channel::ResetStats()
{
    int n;
    int k;
    _channelCritSect->Enter();
    _lastPayloadType = -1;
    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
    {
        _payloadStats[n].payloadType = -1;
        _payloadStats[n].newPacket   = true;
        for(k = 0; k < MAX_NUM_FRAMESIZES; k++)
        {
            _payloadStats[n].frameSizeStats[k].frameSizeSample = 0;
            _payloadStats[n].frameSizeStats[k].maxPayloadLen   = 0;
            _payloadStats[n].frameSizeStats[k].numPackets      = 0;
            _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0;
            _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0;
        }
    }
    _beginTime = TickTime::MillisecondTimestamp();
    _totalBytes = 0;
    _channelCritSect->Leave();
}

WebRtc_Word16
Channel::Stats(CodecInst& codecInst, ACMTestPayloadStats& payloadStats)
{
    _channelCritSect->Enter();
    int n;
    payloadStats.payloadType = -1;
    for(n = 0; n < MAX_NUM_PAYLOADS; n++)
    {
        if(_payloadStats[n].payloadType == codecInst.pltype)
        {
            memcpy(&payloadStats, &_payloadStats[n], sizeof(ACMTestPayloadStats));
            break;
        }
    }
    if(payloadStats.payloadType == -1)
    {
        _channelCritSect->Leave();
        return -1;
    }
    for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
    {
        if(payloadStats.frameSizeStats[n].frameSizeSample == 0)
        {
            _channelCritSect->Leave();
            return 0;
        }
        payloadStats.frameSizeStats[n].usageLenSec =
            (double)payloadStats.frameSizeStats[n].totalEncodedSamples
            / (double)codecInst.plfreq;

        payloadStats.frameSizeStats[n].rateBitPerSec =
            payloadStats.frameSizeStats[n].totalPayloadLenByte * 8 /
            payloadStats.frameSizeStats[n].usageLenSec;

    }
    _channelCritSect->Leave();
    return 0;
}

void
Channel::Stats(WebRtc_UWord32* numPackets)
{
    _channelCritSect->Enter();
    int k;
    int n;
    memset(numPackets, 0, MAX_NUM_PAYLOADS * sizeof(WebRtc_UWord32));
    for(k = 0; k < MAX_NUM_PAYLOADS; k++)
    {
        if(_payloadStats[k].payloadType == -1)
        {
            break;
        }
        numPackets[k] = 0;
        for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
        {
            if(_payloadStats[k].frameSizeStats[n].frameSizeSample == 0)
            {
                break;
            }
            numPackets[k] +=
                _payloadStats[k].frameSizeStats[n].numPackets;
        }
    }
    _channelCritSect->Leave();
}

void
Channel::Stats(WebRtc_UWord8* payloadType, WebRtc_UWord32* payloadLenByte)
{
    _channelCritSect->Enter();

    int k;
    int n;
    memset(payloadLenByte, 0, MAX_NUM_PAYLOADS * sizeof(WebRtc_UWord32));
    for(k = 0; k < MAX_NUM_PAYLOADS; k++)
    {
        if(_payloadStats[k].payloadType == -1)
        {
            break;
        }
        payloadType[k] = (WebRtc_UWord8)_payloadStats[k].payloadType;
        payloadLenByte[k] = 0;
        for(n = 0; n < MAX_NUM_FRAMESIZES; n++)
        {
            if(_payloadStats[k].frameSizeStats[n].frameSizeSample == 0)
            {
                break;
            }
            payloadLenByte[k] += (WebRtc_UWord16)
                _payloadStats[k].frameSizeStats[n].totalPayloadLenByte;
        }
    }

    _channelCritSect->Leave();
}


void
Channel::PrintStats(CodecInst& codecInst)
{
    ACMTestPayloadStats payloadStats;
    Stats(codecInst, payloadStats);
    printf("%s %d kHz\n",
        codecInst.plname,
        codecInst.plfreq / 1000);
    printf("=====================================================\n");
    if(payloadStats.payloadType == -1)
    {
        printf("No Packets are sent with payload-type %d (%s)\n\n",
            codecInst.pltype,
            codecInst.plname);
        return;
    }
    for(int k = 0; k < MAX_NUM_FRAMESIZES; k++)
    {
        if(payloadStats.frameSizeStats[k].frameSizeSample == 0)
        {
            break;
        }
        printf("Frame-size.................... %d samples\n",
            payloadStats.frameSizeStats[k].frameSizeSample);
        printf("Average Rate.................. %.0f bits/sec\n",
            payloadStats.frameSizeStats[k].rateBitPerSec);
        printf("Maximum Payload-Size.......... %d Bytes\n",
            payloadStats.frameSizeStats[k].maxPayloadLen);
        printf("Maximum Instantaneous Rate.... %.0f bits/sec\n",
            ((double)payloadStats.frameSizeStats[k].maxPayloadLen * 8.0 *
            (double)codecInst.plfreq) /
            (double)payloadStats.frameSizeStats[k].frameSizeSample);
        printf("Number of Packets............. %u\n",
               (unsigned int)payloadStats.frameSizeStats[k].numPackets);
        printf("Duration...................... %0.3f sec\n\n",
            payloadStats.frameSizeStats[k].usageLenSec);

    }

}

WebRtc_UWord32
Channel::LastInTimestamp()
{
    WebRtc_UWord32 timestamp;
    _channelCritSect->Enter();
    timestamp = _lastInTimestamp;
    _channelCritSect->Leave();
    return timestamp;
}

double
Channel::BitRate()
{
    double rate;
    WebRtc_UWord64 currTime = TickTime::MillisecondTimestamp();
    _channelCritSect->Enter();
    rate =   ((double)_totalBytes * 8.0)/ (double)(currTime - _beginTime);
    _channelCritSect->Leave();
    return rate;
}

} // namespace webrtc
