/*
 * #%L
 * IsisFish data
 * %%
 * Copyright (C) 2016 Ifremer, Code Lutin, Chatellier Eric
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-2.0.html>.
 * #L%
 */
package scripts;

import java.io.IOException;
import java.util.*;

import org.nuiton.topia.TopiaContext;

import fr.ifremer.isisfish.IsisFishDAOHelper;
import fr.ifremer.isisfish.datastore.RegionStorage;
import fr.ifremer.isisfish.entities.*;
import org.nuiton.util.FileUtil;
import java.io.FileReader;
import org.nuiton.math.matrix.*;
import java.io.File;
import java.io.Writer;
import java.io.FileWriter;


/**
 * Ce script sert à modifier une region de facon informatique car il peut être très
 * couteux en temps de cliquer à de nombreuses reprises dans l'interface graphique.
 * 
 * @author Eric Chatellier
 */
public class FillTargetFactors_SMAC {

    public void run() throws Exception {
        // ouverture d'une region par son nom
        RegionStorage region = RegionStorage.getRegion("Sole_SMAC");
        
        // ouverture d'une transaction pour effectuer toutes les modifications
        TopiaContext tx = region.getStorage().beginTransaction();
        
        // utilisation du contexte dans d'autre methodes
        //fillpossibleMetiersParam(tx);
        //fillStdFactors(tx);
        createTargetSpecies(tx);
        updateMetierSMAC(tx);
        
        // commit : valide les transactions en base de données
        // roolback : annule les modifications en base de données (permet de tester le script)
        tx.commitTransaction();
        //tx.rollbackTransaction();
        
        // close region
        tx.closeContext();
    }

    protected void fillpossibleMetiersParam(TopiaContext tx) {
        SetOfVesselsDAO sovDAO = IsisFishDAOHelper.getSetOfVesselsDAO(tx);
        List<SetOfVessels> sovs = sovDAO.findAll();
        for(SetOfVessels sov : sovs){
            Collection<EffortDescription> strMet = sov.getPossibleMetiers();
              for (EffortDescription ed : strMet) {
                ed.setFishingOperation(1);
                ed.setGearsNumberPerOperation(1); 
            }
        }
    }
    
    /**
     * Modifie les standardisation factors
     * 
     * @param tx transaction
     */

    protected void fillStdFactors(TopiaContext tx) {
        GearDAO gearDAO = IsisFishDAOHelper.getGearDAO(tx);
        List<Gear> gears = gearDAO.findAll();
        for(Gear ge : gears){
            ge.setStandardisationFactor(1);
        }
   
    }
    
    /**
     * cree les target species manquantes
     * 
     * @param tx transaction
     */
    protected void createTargetSpecies(TopiaContext tx) throws IOException {
    TargetSpeciesDAO tsDAO = IsisFishDAOHelper.getTargetSpeciesDAO(tx);
    MetierDAO metierDAO = IsisFishDAOHelper.getMetierDAO(tx);                  
    List<Metier> metiers = metierDAO.findAll();
    SpeciesDAO speciesDAO = IsisFishDAOHelper.getSpeciesDAO(tx);
    List<Species> species = speciesDAO.findAll();
        for (Metier metier : metiers) {
            List<MetierSeasonInfo> msis = metier.getMetierSeasonInfo();
            for (MetierSeasonInfo msi : msis) {
                for(Species sp :species){
                    if(sp.getName().equals("MetaSole")){
                    if(msi.getSpeciesTargetSpecies(sp)==null){
                         TargetSpecies ts = tsDAO.create();
                         String form = "return 1;"; 
                         ts.getTargetFactorEquation().setContent(form);
                         ts.setSpecies(sp) ; 
                         msi.addSpeciesTargetSpecies(ts) ;
                    }
                }
                }
            }
        }
    }

    
    /**
     * Modifie les target factors
     * 
     * @param tx transaction
     */
    protected void updateMetierSMAC(TopiaContext tx) throws IOException {
        MetierDAO metierDAO = IsisFishDAOHelper.getMetierDAO(tx);
        
        // load target factor table
        File fileTargetFactors = new File("InputSoleSMAC/MatrixTargetFactors_glm.nb2Cpue_190216.csv");
        String[] StringGearOrder = {"DRB","GNS","GTR","GTR_90","OTB","TBB","OTH"};
        String[] StringSpeciesOrder = {"Cod","Cuttlefish","RedMullet","Plaice","Scallops","Sole","Squid","Whiting","MetaSole"};
        List <String> gearOrder = Arrays.asList(StringGearOrder);
        List <String> speciesOrder = Arrays.asList(StringSpeciesOrder);
        MatrixND matrixTargetFactors = MatrixFactory.getInstance().create(
                "matrixTargetFactors",
                new List[]{gearOrder,speciesOrder},
                new String[]{"Gear","Species"});        
        matrixTargetFactors.importCSV(new FileReader(fileTargetFactors),new int []{0,0});
        
                
        List<Metier> metiers = metierDAO.findAll();
        for (Metier metier : metiers) {
            String gearName = metier.getGear().getName();
            List<MetierSeasonInfo> msis = metier.getMetierSeasonInfo();
            for (MetierSeasonInfo msi : msis) {
                Collection<TargetSpecies> stsList = msi.getSpeciesTargetSpecies();             
                for (TargetSpecies ts : stsList) {
                    String tsn = ts.getSpecies().getName();
                    if(tsn.equals("MetaSole")){
                    double tf = matrixTargetFactors.getValue(gearName,tsn); 
                    String eq = "return "+ tf + ";";
                    ts.getTargetFactorEquation().setContent(eq);
                    }
                }
            }
        }
    }

    /**
     * Point d'entrée du script.
     */
    public static void main(String[] args) throws Exception {
        FillTargetFactors script = new FillTargetFactors();
        script.run();
        System.out.println("Done: " + new Date());
    }
}
