/* FichothequeLib_Tools - Copyright (c) 2013-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.fichotheque.tools.extraction.corpus;

import java.util.SortedMap;
import java.util.TreeMap;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.CountryItem;
import net.fichotheque.corpus.fiche.FicheItem;
import net.fichotheque.corpus.fiche.FicheItems;
import net.fichotheque.corpus.fiche.GeopointItem;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.extraction.def.FicheFilter;
import net.fichotheque.extraction.def.GroupClause;
import net.fichotheque.extraction.run.FicheGroup;
import net.fichotheque.extraction.run.FicheItemGroupParams;
import net.fichotheque.utils.FicheUtils;
import net.mapeadores.util.geoloc.GeolocUtils;
import net.mapeadores.util.localisation.Country;
import net.mapeadores.util.primitives.DegrePoint;
import net.fichotheque.junction.Junction;


/**
 *
 * @author Vincent Calame
 */
class CountryGroupEngine extends GroupEngine {

    private final GroupClause groupClause;
    private final GroupEngineProvider subGroupEngineProvider;
    private FieldKey fieldKey;
    private GroupBuilder emptyGroupBuilder;
    private final SortedMap<Country, GroupBuilder> treeMap = new TreeMap<Country, GroupBuilder>();

    CountryGroupEngine(GroupClause groupClause, GroupEngineProvider subGroupEngineProvider) {
        this.groupClause = groupClause;
        this.subGroupEngineProvider = subGroupEngineProvider;
        FicheItemGroupParams groupParams = (FicheItemGroupParams) groupClause.getGroupParams();
        if (groupParams != null) {
            fieldKey = groupParams.getFieldKey();
        }
    }

    @Override
    public void add(FicheMeta ficheMeta, FicheFilter ficheFilter, Junction junction) {
        Country country = null;
        if (fieldKey != null) {
            Object obj = FicheUtils.getValue(ficheMeta, fieldKey);
            if (obj != null) {
                if (obj instanceof FicheItem) {
                    country = getCountry((FicheItem) obj);
                } else if (obj instanceof FicheItems) {
                    country = getCountry(((FicheItems) obj).get(0));
                }
            }
        }
        GroupBuilder groupBuilder = getGroupBuilder(country);
        groupBuilder.add(ficheMeta, ficheFilter, junction);
    }

    private Country getCountry(FicheItem ficheItem) {
        if (ficheItem instanceof CountryItem) {
            return ((CountryItem) ficheItem).getCountry();
        } else {
            return null;
        }
    }

    @Override
    public FicheGroup[] toFicheGroupArray() {
        return toGroupArray(treeMap.values(), groupClause, emptyGroupBuilder);
    }

    private GroupBuilder getGroupBuilder(Country country) {
        if (country == null) {
            if (emptyGroupBuilder == null) {
                emptyGroupBuilder = GroupBuilder.newInstance("_", groupClause.getTagNameInfo(), subGroupEngineProvider);
            }
            return emptyGroupBuilder;
        }
        GroupBuilder groupBuilder = treeMap.get(country);
        if (groupBuilder == null) {
            groupBuilder = GroupBuilder.newInstance(country.toString(), groupClause.getTagNameInfo(), subGroupEngineProvider);
            treeMap.put(country, groupBuilder);
            CountryItem countryItem = new CountryItem(country);
            FicheItem[] matchingFicheItemArray;
            DegrePoint degrePoint = GeolocUtils.getCountryGeoloc(country.toString());
            if (degrePoint != null) {
                matchingFicheItemArray = new FicheItem[2];
                GeopointItem geopoint = new GeopointItem(degrePoint.getLatitude(), degrePoint.getLongitude());
                matchingFicheItemArray[1] = geopoint;
            } else {
                matchingFicheItemArray = new FicheItem[1];
            }
            matchingFicheItemArray[0] = countryItem;
            groupBuilder.setMatchingFicheItemArray(matchingFicheItemArray);
        }
        return groupBuilder;
    }

}
