#include "tcp.h"
#include "heartbeat.h"

int main( int argc, char **argv )
{
	fd_set afd;            /* wszystkie deksryptory */
	fd_set readfd;         /* deskryptory do czytania */
	msg_t msg;             /* komunikat */
  	int cnt = sizeof( msg );
	struct timeval tv;     /* czas oczekiwania na heartbeat */
	int s;                 /* gniazdo nasłuchujące */
	int s1;                /* gniazdo połączone */
	int rc;                /* liczba gotowych deskryptorów */
	int missed_heartbeats = 0;  /* liczba zaginionych heratbeat'ow */


	program_name=argv[0];
   
   /* Utworz gniazdo nasłuchujące: adres INADDR_ANY, podany port */
	s = tcp_server( NULL, argv[ 1 ] );

	s1 = accept( s, NULL, NULL );
	if ( s1 <= 0  )
		error( 1, errno, "accept()" );

	tv.tv_sec = T1 + T2;
	tv.tv_usec = 0;

	FD_ZERO( &afd );
	FD_SET( s1, &afd );
	for ( ;; )
	{
		readfd = afd;
		rc = select( s1 + 1, &readfd, NULL, NULL, &tv );
		if ( rc < 0 )
			error( 1, errno, "select()" );
		if ( rc == 0 )		/* timed out */
		{
			if ( ++missed_heartbeats > 3 )
				error( 1, 0, "martwe połączenie\n" );
			error( 0, 0, "brak sygnału heartbeat nr %d\n",
				missed_heartbeats );
			tv.tv_sec = T2;
			continue;
		}
		if ( !FD_ISSET( s1, &readfd ) )
			error( 1, 0, "select() zwrocila niepoprawny deskryptor\n" );
		rc = read( s1, ( char * )&msg + sizeof( msg ) - cnt, cnt);
		if ( rc == 0 )
			error( 1, 0, "Klient zakończyl prace\n" );
		if ( rc < 0 )
			error( 1, errno, "read()" );
		missed_heartbeats = 0;
		tv.tv_sec = T1 + T2;
		cnt -= rc;
		if ( cnt > 0 )
			continue;
		cnt = sizeof( msg );
		switch ( ntohl( msg.type ) )
		{
			case MSG_TYPE1 :
				/* przetwarzaj komunikat typu 1 */
				break;
         case MSG_HEARTBEAT :
				rc = write( s1, ( char * )&msg, sizeof( msg ));
				if ( rc < 0 )
					error( 1, errno, "write()" );
				break;
        	default :
				error( 1, 0, "Nieznany typ komunikatu (%d)\n",
					ntohl( msg.type ) );
		}
	}
	exit( 0 );
}
