/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>

#define SERVER_APPLICATION_RECEIVE_BUF_SIZE 65536
char* receiveBuffer = NULL;

void handleIncomingConnection(int fd);

void usage(void);

int main(int argc, char** argv)
{
	int socketFd;
	int clientFd;
	int retVal;
	int one = 1;
	struct sockaddr_in serverSocketAddress;
	socklen_t socket_length;
	int c;
	int serverPort = 0;
	int pid;
     
	while ((c = getopt (argc, argv, "hp:")) != -1)
	{
		switch (c)
		{
			case 'h':
				usage();
				return 1;
			case 'p':
				serverPort = atoi(optarg);
				break;
			case '?':
			default:
				usage();
				return 1;
		}
	}

	if (!serverPort)
	{
		fprintf(stdout, "-p port not specified\n");
		usage();
		return 1;
	}

	receiveBuffer = malloc(SERVER_APPLICATION_RECEIVE_BUF_SIZE);
	if (!receiveBuffer)
	{
		fprintf(stdout, "failed allocating memory for application receive buffer\n");
		return 1;
	}

	socketFd = socket(PF_INET, SOCK_STREAM, 0); 

	if (socketFd < 0)
	{ 
		perror("Socket creation failed");
		return 1;
	}   

	retVal = setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
	if (retVal)
	{
		perror("Could not set SO_REUSEADDR on socket");
		return 1;
	}

	memset(&serverSocketAddress, 0, sizeof(struct sockaddr_in));
	serverSocketAddress.sin_family = AF_INET;
	serverSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
	serverSocketAddress.sin_port = htons(serverPort);

	retVal = bind(socketFd,(struct sockaddr *)&serverSocketAddress, sizeof(serverSocketAddress));
	if (retVal)
	{
		perror("Could not bind port");
		return 1;
	}

	retVal = listen(socketFd, SOMAXCONN);
  	if (retVal < 0)
	{
		perror("listen system call failed");
  		return 1;
  	}

	pid = fork();
	if (pid < 0) 
	{ 
		perror("error forking process for incoming connection");
		return 1;
	}
	if (pid > 0)
	{ 
		return 0; // we exit the parent cleanly and leave the child process open as a listening server
	}

	socket_length = sizeof(serverSocketAddress);
	while(1)
	{
		clientFd = accept(socketFd, (struct sockaddr *)&serverSocketAddress, &socket_length);
		if (clientFd < 0)
		{
			perror("error from accept call on server");
			return 1;
		}

		pid = fork();
		if (pid < 0) 
		{ 
			perror("error forking process for incoming connection");
			return 1;
		}
		if (pid == 0)
		{ 
			handleIncomingConnection(clientFd);
		}
	}

	return 0;
}

void usage()
{
	fprintf(stdout, "usage: gpnetbenchServer -p PORT [-h]\n");
}

void handleIncomingConnection(int fd)
{
	ssize_t bytes;

	while (1)
	{
		bytes = recv(fd, receiveBuffer, SERVER_APPLICATION_RECEIVE_BUF_SIZE, 0);

		if (bytes <= 0)
		{
			// error from rev, assuming client disconnection
			// this is the end of the child process used for handling 1 client connection
			exit(0);
		}
	}
}
