/*
 *  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 <assert.h>
#include <iostream>

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

using 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->IncomingPayload((WebRtc_Word8*)_payloadData, payloadSize, payloadType, timeStamp);
    status = _receiverACM->IncomingPacket((WebRtc_Word8*)_payloadData, payloadDataSize, rtpInfo);

    //delete [] payloadData;

    

    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;
    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),
_chID(chID),
_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;
}   
