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

#include "tclient_tcp.h"

int main ( int argc, char **argv )
{
    int status, written, osize, opos, ipos, flags, bytes_read, bytes_written;
    int port_num, state, i;
    tc_socket cnx;
    tc_listener lstn;
    char err_msg[256];
    char obuf[256], ibuf[1024];
     char *alist[] ={ "share" };
    unsigned char remote_address[16];

    if ( argc < 2 ) {
	fprintf(stderr, "Usage: test port\n" );
	return 1;
    }
    port_num = atoi(argv[1]);
    status = tc_create_tcp_listener ( port_num, 3, 1, alist,
		&lstn, err_msg );
    printf ( "status of listen(port %d): %d '%s'\n", port_num, status, 
		(status&1) ? "" : err_msg );

    while ( (status&1) == 1 ) {
	status = tc_accept ( lstn, &cnx, &port_num, remote_address,
		sizeof(remote_address), err_msg );
	printf("Status of accept: %d '%s'\n", status, 
		(status&1) ? "OK" : err_msg);
        if ( (status&1) == 0 ) break;
	printf("Remote: %d.%d.%d.%d:%d\n", remote_address[0],
	    remote_address[1], remote_address[2],remote_address[3], port_num );

        state = 0;
        status = tc_start_io ( cnx, 1, ibuf, sizeof(ibuf)-1 );

	while ( tc_io_stall ( cnx, &flags, &bytes_read, &bytes_written ) ) {
	    printf("stall completion, Flags: %d, read: %d, written: %d\n",
		flags, bytes_read, bytes_written );
	    if ( flags&4 ) break;	/* error */
	    if ( flags&1 ) {
	        opos = opos + bytes_written;
	      if ( opos < osize ) tc_start_io (cnx, 0, &obuf[opos], osize-opos);
	      else break;
	    }
	    if ( flags&2 ) {
	        ibuf[bytes_read] = '\0';
	        printf ( "%s\n", ibuf );
	        status = tc_start_io ( cnx, 1, ibuf, sizeof(ibuf)-1 );
	        if ( (status&1) == 0 ) exit ( status );
		for ( i = 0; i < bytes_read && (status&1); i++ ) 
				switch ( state ) {
		    case 0:
			if ( ibuf[i] == '\n' ) state = 1;
			break;
		    case 1:
			if ( ibuf[i] == '\n' ) status = 2160;
			if ( ibuf[i] == '\r' ) state = 2; else state = 0;
			break;
		    case 2:
			if ( ibuf[i] == '\n' ) status = 2160;
			state = 3;
			break;
		    case 3:
			break;
		}
		if ( status == 2160 ) {
		    opos = 0;
		    strcpy ( obuf, "HTTP/1.0 500 dummy\n\n" );
		    status = tc_start_io ( cnx, 0, obuf, osize=strlen(obuf) );
		}
	    }
	}
	status = tc_close ( cnx );
    }
    tc_destroy_listener ( lstn );
    return status;
}
