#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>
#include "../base.h"

#define PORT 23241

int main()
{
	int sockfd, newsockfd;
	int num_r, num_w;
	int errcode;
	socklen_t clilen;
	struct sockaddr_in cli_addr, serv_addr;
	char buff[BUFF_SIZE];
	struct timespec start[3], stop[3];
	double diff_time;
	double result[16];

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) {
		system_error();
	}

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(PORT);
	int optval = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

	errcode = bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr));
	if (errcode == -1) {
		system_error();
	}

	if (listen(sockfd, 5) == -1) {
		system_error();
	}

	while (1) {
		newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
		if (newsockfd == -1) {
			system_error();
		}

		clock_gettime(CLOCK_MONOTONIC, &start[0]);
		write(newsockfd, "GRANT SERVICE", 14);

		/* Get size of image */
		memset(buff, 0, BUFF_SIZE);
		num_r = read(newsockfd, buff, BUFF_SIZE-1);
		int image_size = atoi(buff);
		/* Receive image */
		while (1) {
			memset(buff, 0, BUFF_SIZE);
			num_r = read(newsockfd, buff, BUFF_SIZE-1);
			if (num_r <= 0)
				break;
			printf("Read [%d] bytes.\n", num_r);
		}
		clock_gettime(CLOCK_MONOTONIC, &stop[0]);

#if 0
		clock_gettime(CLOCK_MONOTONIC, &start[1]);
		matrix_mult(times, result);
		show_matrix(result);
		clock_gettime(CLOCK_MONOTONIC, &stop[1]);

		clock_gettime(CLOCK_MONOTONIC, &start[2]);
		int i;
		for (i=0; i<16; i++) {
			memset(buff, 0, BUFF_SIZE);
			sprintf(buff, "%f\n", result[i]);
			write(newsockfd, buff, strlen(buff));
		}
		clock_gettime(CLOCK_MONOTONIC, &stop[2]);

		diff_time = calc_diff_time(&start[0], &stop[0]);
		printf("Read: %f ns\t", diff_time);

		diff_time = calc_diff_time(&start[1], &stop[1]);
		printf("Compute %f ns\t", diff_time);

		diff_time = calc_diff_time(&start[1], &stop[1]);
		printf("Write %f ns\n", diff_time);
#endif

		close(newsockfd);
	}
	close(sockfd);

	return 0;
}

