package ecoparasite.input;

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

/**
 * Permet de stocker les données brutes d'un fichier chargé CSV, avant d'être changé en Classe plus spécifique.
 */
public class RawData {

    /**
     * Stocke les données brutes sous formes de deux ArrayList.
     */
    final private ArrayList<ArrayList<String>> data;

    /**
     * Constructeur.
     * @param data ArrayList qui demande des ArrayList<String> pour faire des lignes/colonnes.
     */
    public RawData(ArrayList<ArrayList<String>> data) {
        this.data = data;
    }

    /**
     * Getter des données brutes. À n'utiliser que pour des opérations compliquées non descriptibles par une fonction.
     * @return ArrayList d'ArrayList de String qui contient les données brutes.
     */
    public ArrayList<ArrayList<String>> getData() {
        return data;
    }

    /**
     * Permet d'avoir un affichage debug du contenu de notre jeu de données.
     * @return La string symbolisant nos données.
     */
    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        for( int i = 0; i < data.size(); i++ )
        {
            ArrayList<String> row = data.get(i);
            for( int j = 0; j < row.size(); j++ ){
                sb.append(row.get(j)).append(" | ");
            }
            sb.append(System.lineSeparator());
        }
        return sb.toString();
    }

    /**
     * Permet d'obtenir le nom des colonnes de notre jeu de données.
     *
     * @return HashSet du nom des colonnes
     */
    public HashSet<String> getColumnsNames(){

        HashSet<String> columns = new HashSet<>();
        for (ArrayList<String> row : data) {
            for (String colName : row) {
                columns.add(colName);
                break;
            }
        }

        return columns;
    }

    /**
     * Permet d'avoir toutes les valeurs associées à la colonne.
     * @param colName Le nom de la colonne dans le fichier CSV
     * @return HashSet des données brutes.
     */
    public HashSet<String> getDataFromColumn( String colName ){

        boolean goodColumn = false;
        HashSet<String> rows = new HashSet<>();

        for( ArrayList<String> row : data ){
            for( String value : row ) {
                if( !goodColumn ) {
                    if (colName.equals(value))
                        goodColumn = true;
                    else
                        break;
                } else { // Si on a trouvé la bonne colonne, on ajoute les éléments.
                    rows.add(value);
                }
            }
            if( goodColumn )
                break;
        }

        return rows;
    }

    /**
     * Permet d'obtenir tous les champs d'une entrée.
     * @param index Entrée que vous voulez obtenir, le minimum est l'entrée 1. Le maximum dépend du Dataframe.
     * @return Une HashMap <colonne, valeur>.
     * @throws RawDataOverflow Si vous avez dépassé le maximum d'entrées du DataFrame.
     */
    public HashMap<String,String> getEntry(int index) throws RawDataOverflow {

        if( index <= 0 ){
            index = 1; // 0 = nombre de colonnes, fallback.
        }

        HashMap<String,String> entry = new HashMap<>();

        for( ArrayList<String> row : data ){
            if( index >= row.size()){
                throw new RawDataOverflow( index, row.size() );
            }
            entry.put( row.getFirst(), row.get( index ) );
        }

        return entry;
    }

}
