#include "fep.h"
#include <stdio.h>
#include <stdlib.h>
#include "network.h"
#include "network_factory.cpp"
#include "time.h"

/* Author: John A. Torres
   The fep_program_32 function creates a new RPC Client which
   sends an fep_reply structure to the ATMS Server. After the
   reply is sent, the ATMS Sends a response and the RPC Client
   is destroyed.
 */

/* Handles the ATMS's response to RPC Call */
void handle_ATMS_response(CLIENT *clnt, void *response)
{
	/* If ATMS reply call fails */
	if (response == NULL)
	{
		clnt_perror(clnt, "RPC call failed");
	}
	/* If ATMS reply is successful */
	else
	{
		printf("Successful RPC call to ATMS...\n");
	}
}

void xfer_replys(CLIENT *clnt, FEP_LINE_LDS *lines, int lines_size, LDS_LOOP *ldsMap)
{
	int i, j; // i == line_index, j == lds_index
	void *rv;

	// Send one reply for every "line" in the FEP
	for (i = 0; i < lines_size; i++)
	{
		fep_reply  fepReply;
		
		// populate reply
		fepReply.reply = SHORTPOLL;
		fepReply.schedule = lines[i].schedule;
		fepReply.lineinfo = lines[i].lineInfo;
		fepReply.kind = (enum polltype) 0;
		fepReply.flag = (enum replykind) 0;
		
		/***********************************
			 This is an update to an extern, this should happen on the Java driver side?? 
		lines[i].schedleSeq += 1;
		lines[i].globalSeq += 51;
		*/

		fepReply.schedule_sequence = lines[i].schedleSeq;
		fepReply.global_sequence = lines[i].globalSeq;
		/************************************
			 Need to find out what appropriate schedule time is: look at uci_unix_simulation_time src code		
		fepReply.schedule_time = 
			uci_unix_simulation_time(uci_simulation_time());	// GMT time
		*/
		fepReply.schedule_time = time(NULL);

		fepReply.user_info1 = lines[i].lineNum;
		fepReply.user_info2 = lines[i].lineNum;
		fepReply.system_key = lines[i].systemKey;

		fepReply.answers.size = 1;
		fepReply.answers.fep_answer_list_u.shortp.count = 1;
		
		/* for each LDS in the Line.... (constructs the short_answer message) */
		for (j = 0; j < lines[i].ldsNum; j++)
		{
			fep_shortanswer fsa;
			int index = lines[i].ldsIndex[j];

			// msg: oa, od, ldsMap[index].dataPack, od, ff
			fsa.msg.message_len = ldsMap[index].length + 2;
			fsa.msg.message[0] = 0x0d;
			fsa.msg.message[1] = 0x0a;
			for (int k = 0; k < ldsMap[index].length; k++)
				fsa.msg.message[2 + k]	= ldsMap[index].dataPack[k];
			int aa = ldsMap[index].length;
			fsa.msg.message[2 + aa] = 0x0d;
			fsa.msg.message[3 + aa] = 0xff;	//????????????? warning ?????

			// info
			fsa.info.poll_error_count = 0; 
			/***************************************
				 Need to find out polltime uci time function src code
			fsa.info.poll_time = uci_unix_simulation_time(uci_simulation_time()); 
			*/
			fsa.info.poll_user_info1 = ldsMap[index].drop;	// drop number
			fsa.info.poll_user_info2 = 1;	//always 1
			fsa.info.retries = 0;
			fsa.info.status = (enum replystatus) 1;
			
			//fepReply.answers.fep_answer_list_u.shortp.answers[j] = fsa;	
			fepReply.answers.fep_answer_list_u.shortp.answers[0] = fsa;	
			
			// send out data
			printf("Transferring line=%d, lds_drop_no=%d...\n", lines[i].lineNum, ldsMap[index].drop);
			rv = fep_reply_xfer_32(&fepReply, clnt);

			/* Handle ATMS response to RPC Call */
			printf("Handling ATMS response...\n");
			handle_ATMS_response(clnt, rv);
		}
	}		
}

/* Creates an RPC Client which communicates with the ATMS through RPC Calls */
CLIENT * create_client(char *host)
{
	CLIENT *clnt;
	
	/* Create RPC Client to communicate with ATMS */
	printf("Preparing to create RPC client...\n");
	clnt = clnt_create(host, /*100090,*/ 103121, 32, "tcp");

	/* Check if client creation failed */ 
	if (clnt == (CLIENT *) NULL)
	{
		fprintf(stderr, "Can't create client to %s\n", host);
		exit(1);
	}
	
	return clnt;
}

/* update_ATMS transfers fep_replys to the ATMS Server. 
	It creates an RPC client, loads data from line_atms.txt and lds_atms.txt,
	updates the ATMS with the fep_reply data, and destroys the RPC client.
 */
void update_ATMS(char *host)
{
	CLIENT *clnt = create_client(host);
	
	/* Load data to be xfered to ATMS */
	int lines_size = 0;
	printf("Loading lines\n");
	FEP_LINE_LDS *lines = load_lines(&lines_size, "./lines_atms.txt");
	printf("Loading ldsMap...\n");
	LDS_LOOP *ldsMap = load_lds("./lds_atms.txt");

	/* Transfer data to ATMS */
	printf("Transferring data to ATMS...\n");
	xfer_replys(clnt, lines, lines_size, ldsMap);

	/* Free allocated memory */
	printf("Freeing lines and ldsMap...\n");
	free(lines);
	free(ldsMap);

	/* Destroy client */
	printf("Destroying client...\n");
	clnt_destroy(clnt);
	printf("Returning to main...\n");
}

/* Main driver function to create an RPC Client, make a single RPC Call to the
   ATMS Server */
int main(int argc, char *argv[]) {
	char *host;

	if (argc < 2)
	{
		printf("usage:  %s server_host\n", argv[0]);
		exit(1);
	}

	/* Create RPC Client to send an fep_reply to ATMS */
	host = argv[1];
	update_ATMS(host);

	return 0;
}
