/*
 *  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 <cctype>
#include <stdio.h>
#include <string.h>

#ifdef WIN32
#include <Windows.h>
#endif

#include "TwoWayCommunication.h"
#include "engine_configurations.h"
#include "PCMFile.h"
#include "utility.h"
#include "trace.h"
#include "common_types.h"

using namespace webrtc;

#define MAX_FILE_NAME_LENGTH_BYTE 500

TwoWayCommunication::TwoWayCommunication(int testMode)
{
    _testMode = testMode;
}

TwoWayCommunication::~TwoWayCommunication()
{
    AudioCodingModule::Destroy(_acmA);
    AudioCodingModule::Destroy(_acmB);

    AudioCodingModule::Destroy(_acmRefA);
    AudioCodingModule::Destroy(_acmRefB);

    delete _channel_A2B;
    delete _channel_B2A;

    delete _channelRef_A2B;
    delete _channelRef_B2A;
#ifdef WEBRTC_DTMF_DETECTION
    if(_dtmfDetectorA != NULL)
    {
        delete _dtmfDetectorA;
    }
    if(_dtmfDetectorB != NULL)
    {
        delete _dtmfDetectorB;
    }
#endif
    _inFileA.Close();
    _inFileB.Close();
    _outFileA.Close();
    _outFileB.Close();
    _outFileRefA.Close();
    _outFileRefB.Close();
}


WebRtc_UWord8
TwoWayCommunication::ChooseCodec(WebRtc_UWord8* codecID_A, WebRtc_UWord8* codecID_B)
{
    AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
    WebRtc_UWord8 noCodec = tmpACM->NumberOfCodecs();
    CodecInst codecInst;
    printf("List of Supported Codecs\n");
    printf("========================\n");
    for(WebRtc_UWord8 codecCntr = 0; codecCntr < noCodec; codecCntr++)
    {
        tmpACM->Codec(codecCntr, codecInst);
        printf("%d- %s\n", codecCntr, codecInst.plname);
    }
    printf("\nChoose a send codec for side A [0]: ");
    char myStr[15] = "";
    fgets(myStr, 10, stdin);
    *codecID_A = (WebRtc_UWord8)atoi(myStr);

    printf("\nChoose a send codec for side B [0]: ");
    fgets(myStr, 10, stdin);
    *codecID_B = (WebRtc_UWord8)atoi(myStr);

    AudioCodingModule::Destroy(tmpACM);
    printf("\n");
    return 0;
}

WebRtc_Word16
TwoWayCommunication::ChooseFile(char* fileName, WebRtc_Word16 maxLen, WebRtc_UWord16* frequencyHz)
{
    WebRtc_Word8 tmpName[MAX_FILE_NAME_LENGTH_BYTE];
    //strcpy(_fileName, "in.pcm");
    //printf("\n\nPlease enter the input file: ");
    fgets(tmpName, MAX_FILE_NAME_LENGTH_BYTE, stdin);
    tmpName[MAX_FILE_NAME_LENGTH_BYTE-1] = '\0';
    WebRtc_Word16 n = 0;

    // removing leading spaces
    while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
        (tmpName[n] != 0) && 
        (n < MAX_FILE_NAME_LENGTH_BYTE))
    {
        n++;
    }
    if(n > 0)
    {
        memmove(tmpName, &tmpName[n], MAX_FILE_NAME_LENGTH_BYTE - n);
    }

    //removing trailing spaces
    n = (WebRtc_Word16)(strlen(tmpName) - 1);
    if(n >= 0)
    {
        while((isspace(tmpName[n]) || iscntrl(tmpName[n])) && 
            (n >= 0))
        {
            n--;
        }
    }
    if(n >= 0)
    {
        tmpName[n + 1] = '\0';
    }

    WebRtc_Word16 len = (WebRtc_Word16)strlen(tmpName);
    if(len > maxLen)
    {
        return -1;
    }    
    if(len > 0)
    {
        strncpy(fileName, tmpName, len+1);
    }
    printf("Enter the sampling frequency (in Hz) of the above file [%u]: ", *frequencyHz);
    fgets(tmpName, 6, stdin);
    WebRtc_UWord16 tmpFreq = (WebRtc_UWord16)atoi(tmpName);
    if(tmpFreq > 0)
    {
        *frequencyHz = tmpFreq;
    }
    return 0;
}

WebRtc_Word16 TwoWayCommunication::SetUp()
{
    _acmA = AudioCodingModule::Create(1);
    _acmB = AudioCodingModule::Create(2);

    _acmRefA = AudioCodingModule::Create(3);
    _acmRefB = AudioCodingModule::Create(4);

    WebRtc_UWord8 codecID_A;
    WebRtc_UWord8 codecID_B;

    ChooseCodec(&codecID_A, &codecID_B);
    CodecInst codecInst_A;
    CodecInst codecInst_B;
    CodecInst dummyCodec;
    _acmA->Codec(codecID_A, codecInst_A);
    _acmB->Codec(codecID_B, codecInst_B);

    _acmA->Codec(6, dummyCodec);

    //--- Set A codecs
    CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
    CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
#ifdef WEBRTC_DTMF_DETECTION
    _dtmfDetectorA = new(DTMFDetector);
    CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA, ACMUSA));
#endif
    //--- Set ref-A codecs
    CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
    CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));

    //--- Set B codecs
    CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
    CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
#ifdef WEBRTC_DTMF_DETECTION
    _dtmfDetectorB = new(DTMFDetector);
    CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB, ACMUSA));
#endif

    //--- Set ref-B codecs
    CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
    CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));

    char fileName[500];
    char refFileName[500];
    WebRtc_UWord16 frequencyHz;
    
    //--- Input A
    strcpy(fileName, "./test/data/audio_coding/testfile32kHz.pcm");
    frequencyHz = 32000;
    printf("Enter input file at side A [%s]: ", fileName);
    ChooseFile(fileName, 499, &frequencyHz);


    _inFileA.Open(fileName, frequencyHz, "rb");

    //--- Output A
    strcpy(fileName, "outA.pcm");
    frequencyHz = 16000;
    printf("Enter output file at side A [%s]: ", fileName);
    ChooseFile(fileName, 499, &frequencyHz);
    _outFileA.Open(fileName, frequencyHz, "wb");
    strcpy(refFileName, "ref_");
    strcat(refFileName, fileName);
    _outFileRefA.Open(refFileName, frequencyHz, "wb");

    //--- Input B
    strcpy(fileName, "./test/data/audio_coding/testfile32kHz.pcm");
    frequencyHz = 32000;
    printf("\n\nEnter input file at side B [%s]: ", fileName);
    ChooseFile(fileName, 499, &frequencyHz);
    _inFileB.Open(fileName, frequencyHz, "rb");

    //--- Output B
    strcpy(fileName, "outB.pcm");
    frequencyHz = 16000;
    printf("Enter output file at side B [%s]: ", fileName);
    ChooseFile(fileName, 499, &frequencyHz);
    _outFileB.Open(fileName, frequencyHz, "wb");
    strcpy(refFileName, "ref_");
    strcat(refFileName, fileName);
    _outFileRefB.Open(refFileName, frequencyHz, "wb");
    
    //--- Set A-to-B channel
    _channel_A2B = new Channel;
    _acmA->RegisterTransportCallback(_channel_A2B);
    _channel_A2B->RegisterReceiverACM(_acmB);
    //--- Do the same for the reference
    _channelRef_A2B = new Channel;
    _acmRefA->RegisterTransportCallback(_channelRef_A2B);
    _channelRef_A2B->RegisterReceiverACM(_acmRefB);

    //--- Set B-to-A channel
    _channel_B2A = new Channel;
    _acmB->RegisterTransportCallback(_channel_B2A);
    _channel_B2A->RegisterReceiverACM(_acmA);
    //--- Do the same for reference
    _channelRef_B2A = new Channel;
    _acmRefB->RegisterTransportCallback(_channelRef_B2A);
    _channelRef_B2A->RegisterReceiverACM(_acmRefA);

    // The clicks will be more obvious when we 
    // are in FAX mode.
    _acmB->SetPlayoutMode(fax);
    _acmRefB->SetPlayoutMode(fax);

    return 0;
}

WebRtc_Word16 TwoWayCommunication::SetUpAutotest()
{
    _acmA = AudioCodingModule::Create(1);
    _acmB = AudioCodingModule::Create(2);

    _acmRefA = AudioCodingModule::Create(3);
    _acmRefB = AudioCodingModule::Create(4);

    CodecInst codecInst_A;
    CodecInst codecInst_B;
    CodecInst dummyCodec;

    _acmA->Codec("ISAC", codecInst_A, 16000);
    _acmB->Codec("L16", codecInst_B, 8000);
    _acmA->Codec(6, dummyCodec);

    //--- Set A codecs
    CHECK_ERROR(_acmA->RegisterSendCodec(codecInst_A));
    CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
#ifdef WEBRTC_DTMF_DETECTION
    _dtmfDetectorA = new(DTMFDetector);
    CHECK_ERROR(_acmA->RegisterIncomingMessagesCallback(_dtmfDetectorA, ACMUSA));
#endif

    //--- Set ref-A codecs
    CHECK_ERROR(_acmRefA->RegisterSendCodec(codecInst_A));
    CHECK_ERROR(_acmRefA->RegisterReceiveCodec(codecInst_B));

    //--- Set B codecs
    CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
    CHECK_ERROR(_acmB->RegisterReceiveCodec(codecInst_A));
#ifdef WEBRTC_DTMF_DETECTION
    _dtmfDetectorB = new(DTMFDetector);
    CHECK_ERROR(_acmB->RegisterIncomingMessagesCallback(_dtmfDetectorB, ACMUSA));
#endif

    //--- Set ref-B codecs
    CHECK_ERROR(_acmRefB->RegisterSendCodec(codecInst_B));
    CHECK_ERROR(_acmRefB->RegisterReceiveCodec(codecInst_A));

    char fileName[500];
    char refFileName[500];
    WebRtc_UWord16 frequencyHz;


    //--- Input A
    strcpy(fileName, "./test/data/audio_coding/testfile32kHz.pcm");
    frequencyHz = 16000;
    _inFileA.Open(fileName, frequencyHz, "rb");

    //--- Output A
    strcpy(fileName, "./src/modules/audio_coding/main/test/outAutotestA.pcm");
    frequencyHz = 16000;
    _outFileA.Open(fileName, frequencyHz, "wb");
    strcpy(refFileName, "./src/modules/audio_coding/main/test/ref_outAutotestA.pcm");
    _outFileRefA.Open(refFileName, frequencyHz, "wb");

    //--- Input B
    strcpy(fileName, "./test/data/audio_coding/testfile32kHz.pcm");
    frequencyHz = 16000;
    _inFileB.Open(fileName, frequencyHz, "rb");

    //--- Output B
    strcpy(fileName, "./src/modules/audio_coding/main/test/outAutotestB.pcm");
    frequencyHz = 16000;
    _outFileB.Open(fileName, frequencyHz, "wb");
    strcpy(refFileName, "./src/modules/audio_coding/main/test/ref_outAutotestB.pcm");
    _outFileRefB.Open(refFileName, frequencyHz, "wb");

    //--- Set A-to-B channel
    _channel_A2B = new Channel;
    _acmA->RegisterTransportCallback(_channel_A2B);
    _channel_A2B->RegisterReceiverACM(_acmB);
    //--- Do the same for the reference
    _channelRef_A2B = new Channel;
    _acmRefA->RegisterTransportCallback(_channelRef_A2B);
    _channelRef_A2B->RegisterReceiverACM(_acmRefB);

    //--- Set B-to-A channel
    _channel_B2A = new Channel;
    _acmB->RegisterTransportCallback(_channel_B2A);
    _channel_B2A->RegisterReceiverACM(_acmA);
    //--- Do the same for reference
    _channelRef_B2A = new Channel;
    _acmRefB->RegisterTransportCallback(_channelRef_B2A);
    _channelRef_B2A->RegisterReceiverACM(_acmRefA);

    // The clicks will be more obvious when we 
    // are in FAX mode.
    _acmB->SetPlayoutMode(fax);
    _acmRefB->SetPlayoutMode(fax);

    return 0;
}

void
TwoWayCommunication::Perform()
{
    if(_testMode == 0)
    {
        printf("Running TwoWayCommunication Test");
        WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- TwoWayCommunication ----------");
        SetUpAutotest();
    }
    else
    {
        SetUp();
    }
    unsigned int msecPassed = 0;
    unsigned int secPassed  = 0;

    WebRtc_Word32 outFreqHzA = _outFileA.SamplingFrequency();
    WebRtc_Word32 outFreqHzB = _outFileB.SamplingFrequency();

    AudioFrame audioFrame;

    CodecInst codecInst_B;
    CodecInst dummy;

    _acmB->SendCodec(codecInst_B);

    if(_testMode != 0)
    {
        printf("\n");
        printf("sec:msec                   A                                                  B\n");
        printf("--------                 -----                                              -----\n");
    }

    while(!_inFileA.EndOfFile() && !_inFileB.EndOfFile())
    {
        _inFileA.Read10MsData(audioFrame);
        _acmA->Add10MsData(audioFrame);
        _acmRefA->Add10MsData(audioFrame);

        _inFileB.Read10MsData(audioFrame);
        _acmB->Add10MsData(audioFrame);
        _acmRefB->Add10MsData(audioFrame);


        _acmA->Process();
        _acmB->Process();
        _acmRefA->Process();
        _acmRefB->Process();

        _acmA->PlayoutData10Ms(outFreqHzA, audioFrame);
        _outFileA.Write10MsData(audioFrame);

        _acmRefA->PlayoutData10Ms(outFreqHzA, audioFrame);
        _outFileRefA.Write10MsData(audioFrame);

        _acmB->PlayoutData10Ms(outFreqHzB, audioFrame);
        _outFileB.Write10MsData(audioFrame);

        _acmRefB->PlayoutData10Ms(outFreqHzB, audioFrame);
        _outFileRefB.Write10MsData(audioFrame);

        msecPassed += 10;
        if(msecPassed >= 1000)
        {
            msecPassed = 0;
            secPassed++;
        }
        if(((secPassed%5) == 4) && (msecPassed == 0))
        {
            if(_testMode != 0)
            {
                printf("%3u:%3u  ", secPassed, msecPassed);
            }
            _acmA->ResetEncoder();
            if(_testMode == 0)
            {
                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- Errors epected");
                printf(".");
            }
            else
            {
                printf("Reset Encoder (click in side B)               ");
                printf("Initialize Sender (no audio in side A)\n");
            }
            CHECK_ERROR(_acmB->InitializeSender());
        }
        if(((secPassed%5) == 4) && (msecPassed >= 990))
        {
            if(_testMode == 0)
            {
                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "----- END: Errors epected");
                printf(".");
            }
            else
            {
                printf("%3u:%3u  ", secPassed, msecPassed);
                printf("                                              ");
                printf("Register Send Codec (audio back in side A)\n");
            }
            CHECK_ERROR(_acmB->RegisterSendCodec(codecInst_B));
            CHECK_ERROR(_acmB->SendCodec(dummy));
        }
        if(((secPassed%7) == 6) && (msecPassed == 0))
        {
            CHECK_ERROR(_acmB->ResetDecoder());
            if(_testMode == 0)
            {
                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "---------- Errors epected");
                printf(".");
            }
            else
            {
                printf("%3u:%3u  ", secPassed, msecPassed);
                printf("Initialize Receiver (no audio in side A)      ");
                printf("Reset Decoder\n");
            }
            CHECK_ERROR(_acmA->InitializeReceiver());
        }
        if(((secPassed%7) == 6) && (msecPassed >= 990))
        {
            if(_testMode == 0)
            {
                WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, "----- END: Errors epected");
                printf(".");
            }
            else
            {
                printf("%3u:%3u  ", secPassed, msecPassed);
                printf("Register Receive Coded (audio back in side A)\n");
            }
            CHECK_ERROR(_acmA->RegisterReceiveCodec(codecInst_B));
        }
        //Sleep(9);
    }
    if(_testMode == 0)
    {
        printf("Done!\n");
    }

#ifdef WEBRTC_DTMF_DETECTION
    printf("\nDTMF at Side A\n");
    _dtmfDetectorA->PrintDetectedDigits();

    printf("\nDTMF at Side B\n");
    _dtmfDetectorB->PrintDetectedDigits();
#endif


}

