#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
//int errno;


int main(int argc, char **argv){
	FILE *output;
	struct addrinfo hints, *res;
	int sockfd, new_fd;
	int ret_val;
	int backlog = 10;
	struct sockaddr_storage their_addr;
	socklen_t addr_size;
	unsigned int listen_count = 0;
	void *buf;
	int len;
	int flags;
	int bytes_recv;

        if( ( output = fopen( "./mem.png", "w" ) ) == NULL ) {
                fprintf( stderr, "Error opening mem.png\n");
                exit( 1 );
        }

//fprintf(output, "%s", buf);
//return 0;

	// first, load up address structs with getaddrinfo():
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

	if( (ret_val = getaddrinfo(NULL, "3490", &hints, &res) ) != 0){
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret_val));
		return 2;
	}

	// make a socket:
	sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if(sockfd == -1){
		printf("failed to make a socket!\n");
		//strerror("socket")
		fprintf(stderr, "socket: %s\n", gai_strerror(errno));
		return 2;
	}
	
	// bind it to the port we passed in to getaddrinfo():
	if( bind(sockfd, res->ai_addr, res->ai_addrlen) == -1){
		printf("failed to bind to port!\n");
		//strerror("bind");
		fprintf(stderr, "bind: %s\n", gai_strerror(errno));
		return 2;
	}

	//sleep for 30s
	//sleep(30);
	
	if( (ret_val = listen(sockfd, backlog) ) == -1){
		printf("failed to listen on socket!\n");
		fprintf(stderr, "listen: %s\n", gai_strerror(errno));
		return 2;
	}


	addr_size = sizeof(their_addr);
	//new_fd = -1;
	len = 5511;
	flags = 0;
	buf = malloc(sizeof(char)*len);
	//memset(&buf, '\0', 5511);
	unsigned int bytes_recv_total = 0;

//	while(1==1){

		if( (new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size) ) == -1){
			printf("failed to accept connection!\n");
			fprintf(stderr, "listen: %s\n", gai_strerror(errno));
			//return 2;
		}
		//		sleep(1);
		//		listen_count++;
		//	}

		//sleep(30);
		//flags = 0;

		//len = 5511;

		//buf = malloc(sizeof(char)*len+1);
		//memset(&buf, '\0', 5512);

		while( bytes_recv_total < len){
			if( ( bytes_recv = recv(new_fd, buf, len, flags) ) == -1){
				printf("failed to recv data!\n");
				fprintf(stderr, "recv: %s\n", gai_strerror(errno));
				goto done;
			}else{
				bytes_recv_total += bytes_recv;
				//fwrite ( const void * ptr, size_t size, size_t count, FILE * stream )
				//fprintf(output, "%s", (char *)buf);
			}
			if(bytes_recv == 0){
				printf("remote client closed connection!\n");
				goto done;
			}
		}

		//if(bytes_recv == 0){
		//	printf("remote client closed connection!\n");
		//}else{
			
			printf("%d bytes recieved\n", bytes_recv_total);
			bytes_recv_total = fwrite ( (const void *)buf, 1, bytes_recv_total, output );
			printf("%d bytes written to mem.png\n", bytes_recv_total);

			//printf("message: %s\n", (char *)buf);
			//fprintf(output, "%s", (char *)buf);
		//}


//	}

	done:
	fclose(output);

	printf("done. exiting!\n");	

	freeaddrinfo(res);

	return 0;
}
