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

#ifdef WIN32
#   include <Winsock2.h>
#else
#   include <arpa/inet.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "audio_coding_module.h"
#include "common_types.h"
#include "gtest/gtest.h"

TestPacketization::TestPacketization(RTPStream *rtpStream, WebRtc_UWord16 frequency)
:
_frequency(frequency),
_seqNo(0)
{
    _rtpStream = rtpStream;
}

TestPacketization::~TestPacketization()
{
}

WebRtc_Word32 TestPacketization::SendData(
    const FrameType       /* frameType */,
    const WebRtc_UWord8   payloadType,
    const WebRtc_UWord32  timeStamp,
    const WebRtc_UWord8*  payloadData, 
    const WebRtc_UWord16  payloadSize,
    const RTPFragmentationHeader* /* fragmentation */)
{
    _rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize, _frequency);
    //delete [] payloadData;
    return 1;
}

Sender::Sender()
:
_acm(NULL),
//_payloadData(NULL),
_payloadSize(0),
_timeStamp(0)
{
}

void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream)
{
    acm->InitializeSender();
    struct CodecInst sendCodec;
    int noOfCodecs = acm->NumberOfCodecs();
    int codecNo;
    
    if (testMode == 1)
    {
        //set the codec, input file, and parameters for the current test    
        codecNo = codeId;
        //use same input file for now
        char fileName[] = "./test/data/audio_coding/testfile32kHz.pcm";
        _pcmFile.Open(fileName, 32000, "rb");
    }
    else if (testMode == 0)
    {
        //set the codec, input file, and parameters for the current test    
        codecNo = codeId;
        acm->Codec(codecNo, sendCodec);
        //use same input file for now
        char fileName[] = "./test/data/audio_coding/testfile32kHz.pcm";
        _pcmFile.Open(fileName, 32000, "rb");
    }
    else
    {
        printf("List of supported codec.\n");
        for(int n = 0; n < noOfCodecs; n++)
        {
            acm->Codec(n, sendCodec);
            printf("%d %s\n", n, sendCodec.plname);
        }
        printf("Choose your codec:");
        ASSERT_GT(scanf("%d", &codecNo), 0);
        char fileName[] = "./test/data/audio_coding/testfile32kHz.pcm";
        _pcmFile.Open(fileName, 32000, "rb");
    }

    acm->Codec(codecNo, sendCodec);
    acm->RegisterSendCodec(sendCodec);
    _packetization = new TestPacketization(rtpStream, sendCodec.plfreq);
    if(acm->RegisterTransportCallback(_packetization) < 0)
    {
        printf("Registering Transport Callback failed, for run: codecId: %d: --\n",
                codeId);
    }

    _acm = acm;
}

void Sender::Teardown()
{
    _pcmFile.Close();
    delete _packetization;
}

bool Sender::Add10MsData()
{
    if (!_pcmFile.EndOfFile())
    {
        _pcmFile.Read10MsData(_audioFrame);
        WebRtc_Word32 ok = _acm->Add10MsData(_audioFrame);
        if (ok != 0)
        {
            printf("Error calling Add10MsData: for run: codecId: %d\n",
                codeId);
            exit(1);
        }
        //_audioFrame._timeStamp += _pcmFile.PayloadLength10Ms();
        return true;
    }
    return false;
}

bool Sender::Process()
{
    WebRtc_Word32 ok = _acm->Process();
    if (ok < 0)
    {
        printf("Error calling Add10MsData: for run: codecId: %d\n",
                codeId);
        exit(1);
    }
    return true;
}

void Sender::Run()
{
    while (true)
    {
        if (!Add10MsData())
        {
            break;
        }
        if (!Process()) // This could be done in a processing thread
        {
            break;
        }
    }
}

EncodeToFileTest::EncodeToFileTest()
{
}


void EncodeToFileTest::Perform(int fileType, int codeId, int* codePars, int testMode)
{
    AudioCodingModule *acm = AudioCodingModule::Create(0);
    RTPFile rtpFile;
    char fileName[] = "outFile.rtp";
    rtpFile.Open(fileName, "wb+");
    rtpFile.WriteHeader();

    //for auto_test and logging
    _sender.testMode = testMode;
    _sender.codeId = codeId;

    _sender.Setup(acm, &rtpFile);
    struct CodecInst sendCodecInst;
    if(acm->SendCodec(sendCodecInst) >= 0)
    {
        _sender.Run();
    }
    _sender.Teardown();
    rtpFile.Close();
    AudioCodingModule::Destroy(acm);
}
