/* A router example with high and low priority packets
  CS 6433
 by Turgay Korkmaz
*/

#include "csim.h"
#include <stdio.h>


FACILITY f;		/*pointer for facility */

int LQ, HQ, TLH, TLL, N, NL, NH;  /* state var */
double SIM_TIME;

void packetH();
void packetL();

void sim(int argc,char *argv[])				/*1st process - named sim */
{
    int i;
    short parerror;
    double P, p;
    long seed;
    
    i=1; 
    parerror=0;
    while(i < argc){
	if((strcmp(argv[i], "-s")==0) && (i+1<argc) &&
	   (sscanf(argv[i+1],"%ld", &seed)==1)) i++;
	else if((strcmp(argv[i], "-P")==0) && (i+1<argc) &&
                (sscanf(argv[i+1],"%lf", &P)==1)) i++;
	else parerror = 1;
	i++;
    }
    if((argc<=1) || (parerror==1)){
	fprintf(stderr, "Usage: %s -P percentOfHigh -s valueOfSeed\n",argv[0]);
	exit(-1);
    }
    
    set_model_name("Router with H and L packets");
    create("sim");				/*required create statement*/
    
    reseed(NIL, seed);
    
    LQ=0;
    HQ=0;
    TLH=0;
    TLL=0;
    N=0;
    NL=0;
    NH=0;
    
    f = facility("facility");		/*initialize facility*/
      
    SIM_TIME=2*60*1000;  /* we use ms as the base unit, I will run this sim for 2 min = 2*60*1000 ms,
		    if you want to run it for 2 hours you need to set SIM_TIME to 2 hours = 2*60*60*1000 ms*/
    while(simtime() < SIM_TIME){
	p = uniform(0.0, 1.0);
	if (p < P/100) {
	    packetH(N); 
	}else {
	    packetL(N);
	}
	N++;
	hold(exponential(0.9));
    }
    printf("Perf Results when %3.2f%% is High and %3.2f%% is Low\n",P, 100-P);
    printf("Total %d packets arrived (%d H and %d L)\n",N, NH, NL);
    printf("Loss rate for High Pr Packets = %f%% \n", 100.0*TLH / NH);
    printf("Loss rate for Low Pr Packets = %f%% \n", 100.0*TLL / NL);

    //    report();				/*print report*/
}

void packetH(int id)				/*process customer*/
{
    create("packetH");				/*required create statement*/
    
    set_priority(10);

    NH++;
    if (HQ < 10){
	HQ++;
    } else{
	// printf("H packet %d is lost\n", id);
	TLH++;
	terminate();
    }
    
    reserve(f);				/*reserve facility f*/
    hold(exponential(0.8));		        /*hold service time*/
    release(f);				/*release facility f*/
    
    HQ--;
}


void packetL(int id)				/*process customer*/
{
    create("packetL");				/*required create statement*/
    
    set_priority(5);
    
    NL++;
    if (LQ < 10){
	LQ++;
    }else{
	// printf("L packet %d is lost\n", id);
	TLL++;
	terminate();
    }
    // you can also use use(f,exponential(0.8)); 
    reserve(f);				/*reserve facility f*/
    hold(exponential(0.8));		        /*hold service time*/
    release(f);				/*release facility f*/
    
    LQ--;
}

