package simulationplans;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.*;
import java.io.File;
import java.io.FileReader;
import org.nuiton.util.FileUtil;
import org.nuiton.util.StringUtil;
import org.nuiton.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Collection;
import org.nuiton.math.matrix.*;
import org.nuiton.util.*;
import org.nuiton.topia.*;
import fr.ifremer.isisfish.*;
import fr.ifremer.isisfish.types.*;
import fr.ifremer.isisfish.rule.Rule;
import fr.ifremer.isisfish.rule.RuleHelper;
import fr.ifremer.isisfish.entities.*;
import fr.ifremer.isisfish.simulator.SimulationPlanIndependent;

import fr.ifremer.isisfish.simulator.SimulationPlanContext;
import fr.ifremer.isisfish.simulator.SimulationPlan;
import fr.ifremer.isisfish.datastore.ResultStorage;
import fr.ifremer.isisfish.datastore.RuleStorage;
import fr.ifremer.isisfish.datastore.SimulationStorage;
import fr.ifremer.isisfish.util.Doc;
import org.nuiton.math.matrix.*;

import org.apache.commons.io.FileUtils;
import resultinfos.MatrixCatchWeightPerStrategyMetPerZonePop;
import org.apache.commons.lang3.StringUtils;
/*
 * SensitivityCapturabiliteTroisparamLHS.java
 *
 * Created: 10/09/09
 *
 * @author slehuta
 * @version $Revision: version 3.2.
 *
 * Last update: $Date:  $
 * by : $Author:sigrid $
 */

public class Calibration_GdL_LHS_3param implements SimulationPlanIndependent {

    //public String param_path = "Q:/ISIS-Fish/calibrISIS_1pop/RUN/";
    protected MatrixND matAccessibility;

    /** to use log facility, just put in your code: log.info("..."); */
    static private Log log = LogFactory.getLog(Calibration_GdL_LHS_3param.class);

    //static private final String MATRIX = "LHS_10000_bornes_0-1";
    public String param_MATRIX = "LHS_espace_param";
    private MatrixND matrix = null;
     @Doc("Population which parameters are calibrated")
    public Population param_Population = null;
    int param_parameterNumber = 3;
    public int param_first = 0;
    public int param_simulationNumber = 5;
    //public String param_nom = "truc";
    public String param_directory = "C:/Users/Dedah/Desktop/TheThesis/Works/2022/Isis/Calibration/LHS/";

    int compteurSimus;
    public String [] necessaryResult = {
    };
    
    public String[] getNecessaryResult() {
        return this.necessaryResult;
    }


    /**
     * Permet d'afficher a l'utilisateur une aide sur le plan.
     * @return L'aide ou la description du plan
     */
    public String getDescription() throws Exception {
        // TODO
        return ("fait experiences d'une matrice pour x parametres");
    }
 
    /**
     * Appelmarrage de la simulation, cette methode permet d'initialiser
     * des valeurs
     * @param simulation La simulation pour lequel on utilise cette regle
     */
    public void init(SimulationPlanContext context) throws Exception {
        File dir = new File(param_directory);
        
        matrix = MatrixFactory.getInstance().create(new int[]{param_simulationNumber, param_parameterNumber});
        matrix.importCSV(new FileReader(new File(dir, param_MATRIX + ".csv")), new int[]{0,0});
               
     }
     

    
    /**
     * Call before each simulation
     * @param context plan context
     * @param nextSimulation storage used for next simulation
     * @return true if we must do next simulation, false to stop plan
     * @throws Exception
     */
    public boolean beforeSimulation(SimulationPlanContext context, SimulationStorage nextSimulation) throws Exception {
        int simNum = nextSimulation.getParameter().getSimulationPlanNumber();
        
        if (simNum + param_first < param_simulationNumber) {
            ///////////////////////////////////////////////////////////////////////////////////////////
            // Modif database
         TopiaContext db = nextSimulation.getStorage().beginTransaction();//ouvrir un context pour modifier les donnees
         Population pop = (Population) db.findByTopiaId(param_Population.getTopiaId());          
        
            int ligne = simNum + param_first;
            int[] vligne = {ligne};

            // modif la capturabilite
    /*      Equation eqq = pop.getCapturabilityEquation() ;
            String eqqs  = eqq.getContent();
            // double[] q = {0.041926610,0.33886255,0.4579465,0.4452066,0.2537726,0.9636648};
            String eqqNew = "";
            MatrixND matLigne = matrix.getSubMatrix(0,vligne).reduceDims();
            for(MatrixIterator i=matLigne.iterator(); i.hasNext();){
                i.next();
                eqqNew = eqqNew + i.getValue() + ",";
            }
            eqqs = eqqs.replaceAll("q = \\{.*\\}", "q = \\{" + eqqNew + "\\}");
            eqq.setContent(eqqs);
            System.out.println("Nouvelle eq de capturabilite pour : "+ simNum+" capturabilite = " + eqqs);
     */

  
        String simu = context.getId(); 

        System.out.println("nom de la simu en cours : " + simu);
    
   // String simu = "simu_i0";
          
        String path = param_directory + simNum + "/q.csv";
       
        File Accessibility = new File(path);

        //matAccessibility = MatrixFactory.getInstance().create(Accessibility);
        
        matAccessibility = matrix.getSubMatrix(0,vligne).reduceDims();
        System.out.println("matrice importee" + matAccessibility);
   
       MatrixND c = pop.getCapturability();
       System.out.println("ancienne matrice" + pop + c);
       for (MatrixIterator i = c.iterator(); i.hasNext();){
               i.next() ;
               Object [] sem = i.getSemanticsCoordinates();
               PopulationGroup group = (PopulationGroup)sem[0];
               System.out.println("group.getId() :" + group.getId());
               double q = (double)matAccessibility.getValue(group.getId());
               System.out.println("val q :" + q);System.out.println("val q :" + q);
               i.setValue(q);
               System.out.println("val q :" + q);
       }
       System.out.println("Nouvelle matrice" + pop + c);

            
       db.commitTransaction();
       return true;
     } else {
            return false;
        }
    }

    /**
     * Call after each simulation
     * @param context plan context
     * @param nextSimulation storage used for next simulation
     * @return true if we must do next simulation, false to stop plan
     * @throws Exception
     */
    public boolean afterSimulation(SimulationPlanContext context,
            SimulationStorage lastSimulation) throws Exception{
            //File exportHistoric = new File(param_exportPath);
       /* ResultStorage result = lastSimulation.getResultStorage();
        boolean bool=true;
        compteurSimus=getIteration(lastSimulation); //numero de la simulation qui vient de se terminer
        export(result,compteurSimus);*/
        return true;
    }
    
    /**
    *Calcule la valeur de la fonction d'objectif de la parametrisation utilisee pour la simulation qui vient de s'achever.
    *@param result le numero de la simulation venant de s'achever
    *@return la valeur de fonction d'objectif
    */
        public void export(ResultStorage result, int compteurSimus) throws java.io.IOException{
    }
    
    
    /**
    *Recupere le numero de la simulation renseignee
    *@param simulation storage de la simulationr enseignee
    *@return numero de la simulation renseignee
    */
    public int getIteration(SimulationStorage simulation){          //Il n'y a pas de setIteration
        return simulation.getParameter().getSimulationPlanNumber();
    }
}
