// -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
/*
# Copyright (c) 2000-2001 by the University of Southern California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation in source and binary forms for non-commercial purposes and
# without fee is hereby granted, provided that the above copyright notice
# appear in all copies and that both the copyright notice and this permission
# notice appear in supporting documentation, and that any documentation,
# advertising materials, and other materials related to such distribution and
# use acknowledge that the software was developed by the University of
# Southern California, Information Sciences Institute.  The name of the
# University may not be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THE UNIVERSITY OF SOUTHERN CALIFORNIA MAKES NO REPRESENTATIONS ABOUT THE
# SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS PROVIDED "AS
# IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE.
#
# Other copyrights might apply to parts of this software and are so noted when
# applicable.
# ----------------------------------------------------------------------------
#
# Primary author: Purushotham Kamath
#                 January 2001

#This material is based upon work supported by the Defense Advanced Research
#Projects Agency Information Technology Office, (NGI Multicast Applications 
#and Architecture (NMAA-ADDON), ARPA Order No. H645, Program Code No. 9A20, 
#Issued by DARPA/CMD under Contract No. MDA972-99-C-0022.
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <eventhandler.h>
#include <packet.h>
#include <queue.h>
#include <component.h>
#include <scheduler.h>
#include <ipport.h>
#include <opport.h>

#include <debug.h>

//Main function of the Merger. Contains the main 
//function that couples the components and starts the simulation.

Scheduler * sched;
int numIPPorts; 
OPPort *op;
IPPort **ip;

int main(int argc,  char **argv)
{

	char ipfile[20];
	char opfile[20];
	
	if(argc < 3)
	{
		printf("Usage: merger <Number of input ports> <Buffer size (kBytes)> <OP line speed (Mb/s)>\n");
		exit(0);
	}



	numIPPorts = atoi(argv[1]); 
	int buffersize = atoi(argv[2]);  //Multiples of 1000 bytes
	int oplinespeed = atoi(argv[3]); //Mbps
	

	dprintf("res.cc: main(): Arguments: Number of ip ports: %d\n", numIPPorts);
	dprintf("res.cc: main(): Arguments: OP Line speed: %d Mbps\n", oplinespeed);
	dprintf("res.cc: main(): Arguments: Buffersize : %d\n", buffersize);



	sprintf(opfile, "res0.out");
	op = new OPPort(buffersize, (char *)opfile);   
	ip = new IPPort *[numIPPorts];

	sched = new Scheduler();

//The output interface.
//	op[count]->linespeed = 1E9F;  //1Gbps (Gigabit)
//	op[count]->linespeed = 51.84E6F;  //OC1 
//	op[count]->linespeed = 155.25E6F;  //OC3 
//	op[count]->linespeed = 622.08E6F;  //OC12 
//	op[count]->linespeed = 1.24416E9F;  //OC48 
//	op[count]->linespeed = 2.48832E9F;  //OC96 
//	op[count]->linespeed = 10E9F;  //10Gbps (OC-192)
	op->linespeed = oplinespeed *1E6;

//The input interface consists of an IPPort which accepts the incoming packets,
//a router process which searches for the packet in the cache and the cache itself.
	for(int count = 0; count < numIPPorts; count++)
	{

		sprintf(ipfile, "res%d.in", count);
		ip[count]  = new IPPort(64 , (char *)ipfile);   //Size of input port queue = 64, to accomodate the largest size IP packet.
		ip[count]->portid = count;
		couple(ip[count], op);
	}


	dprintf("res.cc: main(): Entering scheduler loop\n");
	for(int count =0 ; count < numIPPorts; count++)
		ip[count]->read();


	while (1)
		if(!(sched->run()))
			break;


	dprintf("res.cc: main(): No more events to schedule\n");
	
	for(int count =0; count < numIPPorts; count++)
	{
		printf("Input port : %d\n", count);
		printf("---------------\n");
		ip[count]->dumpstats();
		delete ip[count];
		printf("\n");
	}

	printf("Output port :\n");
	printf("---------------\n");
	op->dumpstats();
	delete op;
	printf("\n");
	printf("Test duration: %.9f\n", sched->currenttime - sched->start);	
	
	delete [] ip;
	exit(0);
}
