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

// BWEStandAlone.cpp : Defines the entry point for the console application.
//

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

#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/test/channel_transport/udp_transport.h"

#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestLoadGenerator.h"
#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/TestSenderReceiver.h"

#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"

//#include "vld.h"

class myTransportCB: public UdpTransportData
{
public:
    myTransportCB (RtpRtcp *rtpMod) : _rtpMod(rtpMod) {};
protected:
    // Inherited from UdpTransportData
 void IncomingRTPPacket(const int8_t* incomingRtpPacket,
                        const size_t rtpPacketLength,
                        const int8_t* fromIP,
                        const uint16_t fromPort) override;

 void IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
                         const size_t rtcpPacketLength,
                         const int8_t* fromIP,
                         const uint16_t fromPort) override;

private:
    RtpRtcp *_rtpMod;
};

void myTransportCB::IncomingRTPPacket(const int8_t* incomingRtpPacket,
                                      const size_t rtpPacketLength,
                                      const int8_t* fromIP,
                                      const uint16_t fromPort)
{
    printf("Receiving RTP from IP %s, port %u\n", fromIP, fromPort);
    _rtpMod->IncomingPacket((uint8_t *) incomingRtpPacket, rtpPacketLength);
}

void myTransportCB::IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
                                       const size_t rtcpPacketLength,
                                       const int8_t* fromIP,
                                       const uint16_t fromPort)
{
    printf("Receiving RTCP from IP %s, port %u\n", fromIP, fromPort);
    _rtpMod->IncomingPacket((uint8_t *) incomingRtcpPacket, rtcpPacketLength);
}


int main(int argc, char* argv[])
{
    bool isSender = false;
    bool isReceiver = false;
    uint16_t port;
    std::string ip;
    TestSenderReceiver *sendrec = new TestSenderReceiver();
    TestLoadGenerator *gen;

    if (argc == 2)
    {
        // receiver only
        isReceiver = true;

        // read port
        port = atoi(argv[1]);
    }
    else if (argc == 3)
    {
        // sender and receiver
        isSender = true;
        isReceiver = true;

        // read IP
        ip = argv[1];

        // read port
        port = atoi(argv[2]);
    }

    Trace::CreateTrace();
    Trace::SetTraceFile("BWEStandAloneTrace.txt");
    Trace::set_level_filter(webrtc::kTraceAll);

    sendrec->InitReceiver(port);

    sendrec->Start();

    if (isSender)
    {
        const uint32_t startRateKbps = 1000;
        //gen = new CBRGenerator(sendrec, 1000, 500);
        gen = new CBRFixFRGenerator(sendrec, startRateKbps, 90000, 30, 0.2);
        //gen = new PeriodicKeyFixFRGenerator(sendrec, startRateKbps, 90000, 30, 0.2, 7, 300);
        //const uint16_t numFrameRates = 5;
        //const uint8_t frameRates[numFrameRates] = {30, 15, 20, 23, 25};
        //gen = new CBRVarFRGenerator(sendrec, 1000, frameRates, numFrameRates, 90000, 4.0, 0.1, 0.2);
        //gen = new CBRFrameDropGenerator(sendrec, startRateKbps, 90000, 0.2);
        sendrec->SetLoadGenerator(gen);
        sendrec->InitSender(startRateKbps, ip.c_str(), port);
        gen->Start();
    }

    while (1)
    {
    }

    if (isSender)
    {
        gen->Stop();
        delete gen;
    }

    delete sendrec;

    //uint8_t numberOfSocketThreads = 1;
    //UdpTransport* transport = UdpTransport::Create(0, numberOfSocketThreads);

    //RtpRtcp* rtp = RtpRtcp::CreateRtpRtcp(1, false);
    //if (rtp->InitSender() != 0)
    //{
    //    exit(1);
    //}
    //if (rtp->RegisterSendTransport(transport) != 0)
    //{
    //    exit(1);
    //}

//    transport->InitializeSendSockets("192.168.200.39", 8000);
    //transport->InitializeSendSockets("127.0.0.1", 10000);
    //transport->InitializeSourcePorts(8000);


    return(0);
 //   myTransportCB *tp = new myTransportCB(rtp);
 //   transport->InitializeReceiveSockets(tp, 10000, "0.0.0.0");
 //   transport->StartReceiving(500);

 //   int8_t data[100];
 //   for (int i = 0; i < 100; data[i] = i++);

 //   for (int i = 0; i < 100; i++)
 //   {
 //       transport->SendRaw(data, 100, false);
 //   }



 //   int32_t totTime = 0;
 //   while (totTime < 10000)
 //   {
 //       transport->Process();
 //       int32_t wTime = transport->TimeUntilNextProcess();
 //       totTime += wTime;
 //       Sleep(wTime);
 //   }


    //if (transport)
    //{
    //    // Destroy the Socket Transport module
    //    transport->StopReceiving();
    //    transport->InitializeReceiveSockets(NULL,0);// deregister callback
 //       UdpTransport::Destroy(transport);
    //    transport = NULL;
 //   }

 //   if (tp)
 //   {
 //       delete tp;
 //       tp = NULL;
 //   }

 //   if (rtp)
 //   {
 //       RtpRtcp::DestroyRtpRtcp(rtp);
 //       rtp = NULL;
 //   }


    //return 0;
}
