

#include <iwear/thread.h>
#include <iwear/tcpconnection.h>
#include <iwear/utility.h>
#include <iwear/stopwatch.h>
#include <iwear/conditional.h>
#include <iwear/iwmutex.h>
#include <iomanip>
#include <iostream>

using namespace iwear;
using namespace iwear::net;
// This produces some data and sends it to a socket.
class Source : public Thread
{
private:
protected:
    Conditional& cond;
public:
    Source( Conditional& c ) : cond(c) { }
    void Run( void );
};

void Source::Run( void )
{
    StopWatch sw;
    sw.Start();
    TCPConnection tcp;
    char buf[2000];
    memset(&buf,0,2000);

    tcp.bind(9999);
    tcp.listen();
    Connection* ac = tcp.accept(50);

    while(true)
    {	
	ac->write(&buf,2000,50);
	ac->read(&buf,2000,50);
	sw.Stop();
	cout << std::setprecision(10) << std::fixed << ANSI_RED << "Since last cycle : " << sw.Time() << ANSI_NORMAL << endl;
	sw.Start();
//	cond.Unlock();
//	cond.Signal(true);
    }
}

// This reads some data from a socket and dumps it into /dev/null
class Sink : public Thread
{
private:
protected:
    Conditional& cond;
public:
    Sink( Conditional& c ) : cond(c) { }
    void Run( void );
};

void Sink::Run( void )
{
    StopWatch sw;
    sw.Start();
    TCPConnection tcp;

    tcp.connect("localhost",9999,50);
    char buf[2000];

//    cond.Signal(true);
//    usleep(10000);

    while(true)
    {
//	cond.Wait(false);
	tcp.read(&buf,2000,50);
	tcp.write(&buf,2000,50);
	sw.Stop();
	cout << std::setprecision(10) << ANSI_BLUE << "Since last cycle : " << sw.Time() << ANSI_NORMAL << endl;
	sw.Start();
//	cond.Unlock();
//	cond.Signal(true);
    }
}

int main ( void )
{
    IWMutex m;
    Conditional c(m);
    Source sr(c);
    Sink   si(c);

    sr.Start();
    usleep(1000);
    si.Start();

    while(true) usleep (10000000);
}
