package SimkitOpenDis7Examples.run;

import SimkitOpenDis7Examples.ArrivalProcessOpenDis7;
import SimkitOpenDis7Examples.SimpleServer;
import simkit.Schedule;
import simkit.random.RandomVariate;
import simkit.random.RandomVariateFactory;
import simkit.stat.SimpleStatsTimeVarying;
import simkit.util.SimplePropertyDumper;

/**
 * <h2>Output:</h2><pre>
 * ArrivalProcess.1
 * &nbsp;&nbsp;&nbsp;&nbsp;interarrivalTimeGenerator = Uniform (0.900, 2.200)
 * SimpleServer.2
 * &nbsp;&nbsp;&nbsp;&nbsp;serviceTimeGenerator = Gamma (1.700, 1.800)
 * &nbsp;&nbsp;&nbsp;&nbsp;totalNumberServers = 2
 * Simulation ended at time 100,000.000
 *
 * There have been 64,475 arrivals
 * There have been 64,472 customers served
 * Average number in queue	15.9655
 * Average utilization	0.9819</pre>
 *
 * @author ahbuss
 */
public class RunSimpleServerOpenDis7 {

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        String rvName = "Uniform";
        double lower = 0.9;
        double upper = 2.2;
        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(rvName, lower, upper);
        ArrivalProcessOpenDis7 arrival = new ArrivalProcessOpenDis7(interarrivalTimeGenerator);

        rvName = "Gamma";
        double alpha = 1.7;
        double beta = 1.8;

        RandomVariate serviceTimeGenerator = RandomVariateFactory.getInstance(rvName, alpha, beta);
        int numServ = 2;
        SimpleServer server = new SimpleServer(numServ, serviceTimeGenerator);
        arrival.addSimEventListener(server);

        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
//        server.addPropertyChangeListener(simplePropertyDumper);
//        arrival.addPropertyChangeListener(simplePropertyDumper);

        SimpleStatsTimeVarying numberInQueueStat = new SimpleStatsTimeVarying("numberInQueue");
        SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers");

        server.addPropertyChangeListener(numberInQueueStat);
        server.addPropertyChangeListener(numberAvailableServersStat);

        System.out.println(arrival);
        System.out.println(server);

//        Schedule.setVerbose(true);
//        Schedule.setSingleStep(false);
//        double stopTime = 6.0;
        double stopTime = 100000.0;

        Schedule.stopAtTime(stopTime);

        Schedule.reset();
        numberInQueueStat.reset();
        numberAvailableServersStat.reset();
        Schedule.startSimulation();

        System.out.printf("Simulation ended at time %,.3f%n", Schedule.getSimTime());
        System.out.printf("%nThere have been %,d arrivals%n", arrival.getNumberArrivals());
        System.out.printf("There have been %,d customers served%n", server.getNumberServed());
        System.out.printf("Average number in queue\t%.4f%n", numberInQueueStat.getMean());
        System.out.printf("Average utilization\t%.4f%n", 1.0 - numberAvailableServersStat.getMean() / server.getTotalNumberServers());

        System.out.println("Execution complete.");
        arrival.getChannelOpenDis7().tearDownNetworkInterface();
        System.exit(0); // normal completion
    }
}