package SimkitOpenDis7Examples.run;

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

/**
 * Run a simple server problem and compute statistical measurement of results.
 * <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 abuss@nps.edu
 */
public class RunSimpleServer
{
    /** Default constructor */
    public RunSimpleServer()
    {
        // default constructor
    }
    /**
     * Run a simple program and compute statistical measurement of results.
     * @param args the command line arguments
     */
    public static void main(String args[]) 
    {
        String rvName = "Uniform"; // TODO is enumeration available?
        double lower = 0.9;
        double upper = 2.2;
        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(rvName, lower, upper);
        ArrivalProcess arrival = new ArrivalProcess(interarrivalTimeGenerator);

        rvName = "Gamma"; // TODO is enumeration available?
        double alpha = 1.7;
        double beta = 1.8;

        RandomVariate serviceTimeGenerator = RandomVariateFactory.getInstance(rvName, alpha, beta);
        int numServ = 1;
        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());
    }
}