/*
 * fireflier-client-gnome
 * Copyright (C) 2002  triendl.kj
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * triendl.kj
 * triendl.kj@aon.at
 */

#include <config.h>
#if FF_DEBUG
#include <iostream>
using namespace std;
#endif
#include "fireflier.h"
#include "fireflierIO.h"
#include <unistd.h>



CffIO::CNetworkThread::CNetworkThread()
	: m_bDoRun(false)
	, m_pCurPacket(NULL)
{
}

CffIO::CNetworkThread::~CNetworkThread()
{
}

void CffIO::CNetworkThread::run()
{
	run1();
    
#if FF_DEBUG
			cerr << "got probably disconnected. ending networkThread." << endl;
#endif
	//signal_finished().emit();
}


void CffIO::CNetworkThread::run1()
{
	m_bDoRun = ffIO.connect();

	// tell that the connection process is done (no matter whether successful or not)
	m_semWait.wait(); // wait until gui is ready
	signal_Connection().emit(m_bDoRun);
	
	CCO_RetrieveHeader coMsgType;
	while (m_bDoRun)
	{
		try
		{
			ffIO >> coMsgType;
		}
		catch (CffIO::pCffIOError& err)
		{
			signal_error().emit(err, true);
			m_bDoRun = false;
			break;
		}

#if FF_DEBUG
		cerr << "coMsgType.getCmd()=" << coMsgType.getCmd() << endl;
#endif
		switch (coMsgType.getCmd())
		{
			case ff::CMD_PACKET_AVAIL:
			{
				CCO_RetrieveSimple co;
				try
				{
					ffIO >> co;
				}
				catch (CffIO::pCffIOError& err)
				{
					signal_error().emit(err, true);
					m_bDoRun = false;
				}
#if FF_DEBUG
				cout << "len=" << co.getMsgLen() << endl;
				for (int i = 0; i < co.getMsgLen()-3; i++)
					cout << (unsigned int)(unsigned char)co.getMsgBuf()[i] << " ";
				cout << endl;
				cout << "Received message ... parsing" << endl;
#endif
				m_pCurPacket = CPacket::scanPacket(reinterpret_cast <unsigned char*> (co.getMsgBuf()));
				signal_Packet_avail().emit(m_pCurPacket);
			}
				break;

			case ff::CMD_SOURCE:
			{
				CCO_RetrieveSrc co(m_pCurPacket->len);
				try
				{
					ffIO >> co;
				}
				catch (CffIO::pCffIOError& err)
				{
					signal_error().emit(err, true);
					m_bDoRun = false;
				}
#if FF_DEBUG
				cout << "len=" << co.getMsgLen() << endl;
#endif
				signal_Src_avail().emit(co.getMsgBuf(), co.getMsgLen());
			}
				break;

			case ff::CMD_RULES:
			{
				CCO_RetrieveSimple co;
				try
				{
					ffIO >> co;
				}
				catch (CffIO::pCffIOError& err)
				{
					signal_error().emit(err, true);
					m_bDoRun = false;
				}
#if FF_DEBUG
				cout << "len=" << co.getMsgLen() << endl;
#endif				
				signal_IPTablesRules_avail().emit(co.getMsgBuf(), co.getMsgLen());
			}
				break;
			
			case ff::CMD_URULES:
			{
				CCO_RetrieveSimple co;
				try
				{
					ffIO >> co;
				}
				catch (CffIO::pCffIOError& err)
				{
					signal_error().emit(err, true);
					m_bDoRun = false;
				}
#if FF_DEBUG
				cout << "len=" << co.getMsgLen() << endl;
#endif				
				signal_USpaceRules_avail().emit(co.getMsgBuf(), co.getMsgLen());
			}
				break;
				
			case ff::CMD_AUTH:
			{
				//m_semWait.wait(); // wait until the authentication dialog has ended ssl_write()
				CCO_RetrieveLogin co;
				try
				{
					ffIO >> co;
				}
				catch (CffIO::pCffIOError& err)
				{
					signal_error().emit(err, true);
					m_bDoRun = false;
				}
				signal_Authentication().emit(co.getAuth());
				m_bDoRun = (co.getAuth() != 2);
			}
				break;

			case ff::CMD_UPDATE_CONN:
#if FF_DEBUG
				cout << "connection tracking info update" << endl;
#endif
				//signal_update_ConnectionTracking().emit();
				break;
			
			default:
#if FF_DEBUG
				cerr << "Unknown message !!!" << endl;
#endif
			break;
		}
	}
	
	ffIO.end();
}
