/*
 * An example of server implementation
 * by Hoang Nguyen
 * Feel free to modify and copy the code
 * and use it AT YOUR OWN RISK
*/


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

#include <arpa/inet.h>
#include "msg.h"

#define VERBAL 1
#define IVERBAL if (VERBAL) 

#define CPORT "4000" // assuming the control port is 4000
#define DPORT "4001" // data port is 4001


#define MAX_SERVER 5
#define MAXDATASIZE 512

int no_server = 0;
int serverfd[MAX_SERVER];

char buf[MAXDATASIZE];

void usage() {
	printf("dispatcher server1 port1 server2 port2 server3 port3 .. \n");
}

void serve(int sockfd) {
	int server = rand() % no_server;

	
	msg_t msg, reply;

	printf("Recv request from client\n");
	
	recvMessage(sockfd, &msg);
	
	msg.data[msg.len] = 0;

	printf("\tClient request: %s\n", msg.data);
	printf("\tSend request to the server %d\n", server);
	
	sendRequest(serverfd[server], &msg, &reply);

	reply.data[reply.len] = 0;

	printf("\tServer %d reply %s\n", server, reply.data);
	
	reply.data[reply.len] = 0;

	sprintf(reply.data, "connect to server %d", server);
	reply.len = strlen(reply.data);

	printf("\tReply to client: %s\n", reply.data);

	sendMessage(sockfd, &reply);
	
	printf("\tFinish client request\n");	
	
	close(sockfd);
}

void addServer(char* serverName, char* port) {
	
	printf("Add server %s:%s\n", serverName, port);
	
	int sockfd = connectToServer(serverName, port);

	if (sockfd < 0) {
		printf("\tCannot connect to server %s:%s\n", serverName, port);
		return;
	}

	serverfd[no_server++] = sockfd;
} 


int main(int argc, char* argv[]) {
	int i;	
	// add server
	if (argc == 1 || argc % 2 != 1) {
		usage();
		return 0;
	}

	for (i = 1; i <= argc-1 && i+1 <= argc-1; i += 2) {
		addServer(argv[i], argv[i+1]);
	}

	if (no_server == 0) {
		printf("No servers ready!\n");
		return 0;
	}

	printf("Start dispatcher service on port %s\n", CPORT);
	startServer(CPORT, (void*)(serve));

	for (i = 0; i < no_server; i++)
		close(serverfd[i]);

	return 0;
}