package ecoparasite.population;

import ecoparasite.input.RawData;
import ecoparasite.input.RawDataOverflow;

import java.util.HashMap;
import java.util.HashSet;

/**
 * Permet de parser une population spécifique via les schémas fournis.
 */
public class PopulationParsing {

    /**
     * Permet, à partir d'un objet RawData, de parse les données tel que le fichier parasitesPeru est structuré.
     *
     * @param peruRawData
     * @return Une liste des populations incluses.
     */
    public static HashSet<Population> parseParasitesPeru(RawData peruRawData ){

        HashMap<String,Population> response = new HashMap<>();

        int index = 1;
        try {
            while(true){ // Tant que l'on ne fait pas de débordements d'entrées.

                HashMap<String,String> fields = peruRawData.getEntry(index);

                String espece = fields.get("Espèce");
                String parametre = fields.get("Paramètre");

                // Récupère la population si elle existe déjà.
                Population population = null;
                if( response.containsKey( espece ) ){
                    population = response.get(espece);
                } else {
                    population = new Population(espece);
                    response.put(espece, population);
                }

                // Traiter le total
                if( fields.containsKey( "Total" ) ){
                    if( population.getTotal() == null ){
                        population.setTotal( new PopulationArgs() );
                    }
                    PopulationParsing.applyValueForParasitesPeru( population.getTotal(), parametre, fields.get("Total") );
                }

                // Traiter les années.
                for( String k:  fields.keySet() ){
                    if( k.equals( "Total" ) || k.equals("Paramètre") || k.equals("Espèce") ) // Déjà traité. Pas des années.
                        continue;

                    Integer year = Integer.parseInt(k);

                    PopulationArgs popArgsYear = null;
                    if( !population.getPerYear().containsKey(year) ){
                        popArgsYear = new PopulationArgs( year );
                        population.getPerYear().put(year, popArgsYear);
                    } else {
                        popArgsYear = population.getPerYear().get(year);
                    }

                    PopulationParsing.applyValueForParasitesPeru( popArgsYear, parametre, fields.get(k) );
                }

                response.put( espece, population );
                index++;
            }
        } catch (RawDataOverflow e){ // Débordement, on a atteint la fin de l'objet RawData.
            // Stop.
        }

        return new HashSet<Population>( response.values() );
    }

    /**
     * Permet d'appliquer la valeur au paramètre respectif en se basant sur le nom de la colonne.
     *
     * @param populationArgs Les paramètres de la population actuelle.
     * @param column Le nom de la colonne dans le fichier CSV
     * @param value La valeur a affecter
     */
    private static void applyValueForParasitesPeru( PopulationArgs populationArgs, String column, String value ){
        switch( column ){
            case "N":
                populationArgs.setNumber(Integer.parseInt(value));
                break;
            case "Longueur moyenne ± SD (cm)":
                populationArgs.setLength( PopulationArgInterval.fromString( value ) );
                break;
            case "Poids moyen ± SD (g)":
                populationArgs.setWidth( PopulationArgInterval.fromString( value ) );
                break;
            case "Prévalence (%)":
                populationArgs.setPrevalence( PopulationArgInterval.fromString( value ) );
                break;
            case "IC 95%":
                populationArgs.setIc( PopulationArgInterval.fromString( value ) );
                break;
            case "Intensité moyenne (étendue)":
                populationArgs.setIntensity( Double.parseDouble( value.split( " " )[0] ) );
                break;
            case "Abondance moyenne":
                populationArgs.setAbondance( Double.parseDouble( value ) );
                break;
            default:
                break;
        }
    }

}
