package application;

import java.io.BufferedWriter;
import java.io.FileWriter;

import nonrepairable_systems.ColdPartialRedundancySystem;
import nonrepairable_systems.ColdStandbySytem;

import repairable_systems.ActivePartialRedundancySystem;
import repairable_systems.ColdStandByPartialRedundancySystem;

/**
 * @author jnunezf
 * Aplicacion que genera un resumen CSV de analisis de confiabilidad
 * para distintas configuraciones de sistemas, distintos numeros de subsistemas
 * e instantes de tiempo.
 */
public class Main {
    
    public static void main(String[] args) {
        
        
        /**
         * Se generan resumenes csv de analisis de confiabilidad
         */

        //se genera csv para el CASO I
        //generateCSVResumeOfColdStanbySystem(3, 1, 5, 0.0, 100, 5000.00);
        
        //se genera csv para el CASO II
        //generateCSVResumeOfColdPartialRedundancySystem(3, 11, 14, 2, 6, 8, 0.0, 100, 5000.00);

        //se genera csv para el CASO III
       //generateCSVResumeOfActivePartialRedundancySystem(3, 1, 3, 2, 1, 2, 0.0, 1E1, 1E4);       

        //se genera csv para el CASO IV
        //generateCSVResumeOfColdStandbyPartialRedundancySystem(3, 1, 5, 0.0, 1E1, 1E4);
       
    }

    /**
     *
     * @param nmin  tamano minimo de un sistema
     * @param nstep saltos entre tamanos de sistemas
     * @param nmax  tamano maximo de un sistema
     */
    private static void generateCSVResumeOfColdStandbyPartialRedundancySystem(
            int nmin, int nstep, int nmax, double tmin, double tstep, double tmax){

        try{

            long startTime;

            BufferedWriter outputFile =
                    new BufferedWriter(new FileWriter("ColdStandbyPartialRedundancySystem.csv"));

            for (int n = nmin; n < nmax+1; n+=nstep) {
               
                    int k = 1;
                    int r = 2;
                    int m = 1;
                    
                    double lambda = n * (Math.random() * Math.pow(2400, -1) + Math.pow(1200, -1));
                    double mu = 1/(15 * Math.random() + 5);

                    outputFile.write("\n(n, k, r, m)\t("+ n + ", " + k + ", " + r + ", " + m +")");
                    outputFile.write("\t\nLAMBDA\t" + lambda + "\nMU\t" + mu);                    

                    ColdStandByPartialRedundancySystem system = new
                            ColdStandByPartialRedundancySystem(n, k, r, m, lambda, mu);
                    
                    outputFile.write("\n\tP_i\t");
                    for (int s = 0; s < (n+m+1); s++) {
                        outputFile.write(system.getIthSteadyStateProbability(s) + "\t");

                    }

                    outputFile.write("\n\tR_s(t)\t");
                    for (double t = tmin; t < tmax+1; t+=tstep) {
                        outputFile.write(system.getReliabilityOfSystem(t) + "\t");                        
                    }                        

                    outputFile.write("\n\tA\t" + system.getAvailability());
                    outputFile.write("\n\tMTBF\t" + system.getMTBF());
                    outputFile.write("\n\tMTBR\t" + system.getMTBR());
                
            }

            outputFile.close();
        }catch (Exception e){
            System.err.println("Error: " + e.getMessage());
        }

    }

     /**
     *
     * @param nmin  tamano minimo de un sistema
     * @param nstep saltos entre tamanos de sistemas
     * @param nmax  tamano maximo de un sistema
     */
    private static void generateCSVResumeOfActivePartialRedundancySystem(
            int nmin, int nstep, int nmax, int kmin, int kstep, int kmax, 
            double tmin, double tstep, double tmax){

        try{

            BufferedWriter outputFile =
                    new BufferedWriter(new FileWriter("ActivePartialRedundancySystem.csv"));

            for (int n = nmin; n < nmax+1; n+=nstep) {
                for (int k = kmin; k < kmax+1; k+=kstep){

                    int r = 2;
                    double lambda = n * (Math.random() * Math.pow(2400, -1) + Math.pow(1200, -1));
                    double mu = 1/(15 * Math.random() + 5);

                    outputFile.write("(n, k, r)\t("+ n + ", " + k + ", " + r + ")");
                    outputFile.write("\t\nLAMBDA\t" + lambda + "\nMU\t" + mu);

                    ActivePartialRedundancySystem system = new
                            ActivePartialRedundancySystem(n, k, r, lambda, mu);

                    outputFile.write("\n\tP_i\t");
                    for (int s = 0; s < (n - k + 2); s++) {
                        outputFile.write(system.getIthSteadyStateProbability(s) + "\t");

                    }

                    outputFile.write("\n\tR_s(t)\t");
                    for (double t = tmin; t < tmax+1; t+=tstep) {
                        outputFile.write(system.getReliabilityOfSystem(t) + "\t");                        
                    }                        
                    
                    outputFile.write("\n\tA\t" + system.getAvailability());
                    outputFile.write("\n\tMTBF\t" + system.getMTBF());
                    outputFile.write("\n\tMTBR\t" + system.getMTBR());

                }
            }

            outputFile.close();
        }catch (Exception e){
            System.err.println("Error: " + e.getMessage());
        }

    }

     /**
     *
     * @param nmin  tamano minimo de un sistema
     * @param nstep saltos entre tamanos de sistemas
     * @param nmax  tamano maximo de un sistema
     * @param kmin  tamano maximo de subsistemas en operacion
     * @param kstep saltos subsistemas en operacion
     * @param kmax  tamano maximo de subsistemas en operacion
     * @param tmin  instante inicial de tiempo
     * @param tstep saltos entre instantes de tiempo
     * @param tmax  instante final de tiempo
     */
    private static void generateCSVResumeOfColdPartialRedundancySystem(
            int nmin, int nstep, int nmax, int kmin, int kstep, int kmax, 
            double tmin, double tstep, double tmax){

        try{

            long startTime;
            
            BufferedWriter outputFile =
                    new BufferedWriter(new FileWriter("ColdPartialRedundancySystem.csv"));

            for (int n = nmin; n < nmax+1; n+=nstep) {
                
                for (int k = kmin; k<kmax+1 && (k < n); k+=kstep) {
                    
                    double[] lambda = new double[n];
                    for (int i = 0; i < n; i++) {
                        lambda[i] = (n-k+1) * (Math.random() * Math.pow(2400 * k, -1) + Math.pow(1200 * k, -1));
                    }

                    double[] MTTRs = new double[n];
                    for (int i = 0; i < MTTRs.length; i++) {
                        MTTRs[i] = 15 * Math.random() * 5;
                    }

                    outputFile.write("n " + n + " k " + k + " \n" + "LAMBDA ");
                    for (int component = 0; component < n; component++) {
                        outputFile.write(lambda[component] + " ");
                    }
                    outputFile.write("\n" + "MTTRs ");
                    for (int component = 0; component < n; component++) {
                        outputFile.write(MTTRs[component] + " ");
                    }

                    ColdPartialRedundancySystem system = new ColdPartialRedundancySystem(lambda, MTTRs, k);

                    outputFile.write("\nLAMBDA_MEAN " + system.getLambdaMean());

                    double MTTF = system.getMTTF();
                    double MTTR = system.getMTTR();

                    outputFile.write("\nMTTF " + MTTF);
                    outputFile.write("\nMTTR " + MTTR);
                    outputFile.write("\nAvailability " + system.getAvailability());

                    outputFile.write("\nR_s(t) ");

                    long meanTime = 0;
                    for (double t = tmin; t < tmax + tstep; t += tstep) {

                        startTime = System.nanoTime();
                        double Rs_t = system.getReliabilityOfSystem(t);
                        meanTime += System.nanoTime() - startTime;

                        outputFile.write(Rs_t + " ");

                    }
                    meanTime = meanTime / (long) ((tmax - tmin) / tstep);
                    outputFile.write("\nMeanTime[nanosec] " + meanTime + "\n\n");

                }
            }

            outputFile.close();
        }catch (Exception e){
            System.err.println("Error: " + e.getMessage());
        }

    }

    /**
     *
     * @param nmin  tamano minimo de un sistema
     * @param nstep saltos entre tamanos de sistemas
     * @param nmax  tamano maximo de un sistema
     * @param tmin  instante inicial de tiempo
     * @param tstep saltos entre instantes de tiempo
     * @param tmax  instante final de tiempo
     */
    private static void generateCSVResumeOfColdStanbySystem(
            int nmin, int nstep, int nmax,
            double tmin, double tstep, double tmax){

        try{
            long startTime;

            BufferedWriter outputFile =
                    new BufferedWriter(new FileWriter("ColdStandbySystem.csv"));

            for (int n = nmin; n < nmax+1; n+=nstep) {
                
                double[] lambda = new double[n];
                for (int i = 0; i < n; i++) {                 
                    lambda[i] =  n * (Math.random() * Math.pow(2400, -1) + Math.pow(1200, -1));                    
                }                                                
                
                double[] MTTRs = new double[n];
                for (int i=0; i<MTTRs.length; i++){
                    MTTRs[i] = 15 * Math.random() + 5;
                }
                
                outputFile.write("n " + n + "\n" + "LAMBDA ");
                for (int component = 0; component < n; component++) {
                    outputFile.write(lambda[component] + " ");
                }                

                outputFile.write("\n" + "MTTRs ");
                for (int component = 0; component < n; component++) {
                    outputFile.write(MTTRs[component] + " ");
                }

                ColdStandbySytem system = new ColdStandbySytem(lambda, MTTRs);

                double MTTF = system.getMTTF();
                double MTTR = system.getMTTR();
                outputFile.write("\nMTTF " + MTTF);
                outputFile.write("\nMTTR " + MTTR);
                outputFile.write("\nAvailability " + system.getAvailability());


                for (int component = 0; component < n; component++) {
                    outputFile.write("\nR_" + (component+1) + "(t) ");
                    for (double t = tmin; t < tmax+tstep; t += tstep) {
                        double Ri_t = system.getReliabilityOfIthComponent(component, t);
                        outputFile.write(Ri_t + " ");
                    }                    
                }

                outputFile.write("\nR_s(t) ");
                long meanTime = 0;
                for (double t = tmin; t < tmax+tstep; t += tstep) {
                       
                    startTime = System.nanoTime( );                        
                    double Rs_t = system.getReliabilityOfSystem(t);
                    meanTime += System.nanoTime( ) - startTime;

                    outputFile.write(Rs_t + " ");
                }
                meanTime = meanTime / (long)((tmax -tmin)/ tstep);
                
                outputFile.write("\nMeanTime[nanosec] " + meanTime + "\n\n");

            }

            outputFile.close();
        }catch (Exception e){
            System.err.println("Error: " + e.getMessage());
        }

    }

}
