/* FichothequeLib_Tools - Copyright (c) 2024 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.thesaurus.sync;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.fichotheque.thesaurus.sync.MotcleSync;
import net.fichotheque.thesaurus.sync.ThesaurusSync;
import net.fichotheque.utils.SyncUtils;


/**
 *
 * @author Vincent Calame
 */
public class ThesaurusSyncBuilder {

    private final Set<String> motcleSet = new HashSet<String>();
    private final List<MotcleSyncBuilder> firstLevelList = new ArrayList<MotcleSyncBuilder>();

    public ThesaurusSyncBuilder() {

    }

    public ThesaurusSyncBuilder addFirstLevel(MotcleSyncBuilder motcleSyncBuilder) {
        firstLevelList.add(motcleSyncBuilder);
        motcleSet.add(motcleSyncBuilder.getIdalpha());
        return this;
    }

    public ThesaurusSyncBuilder addChild(MotcleSyncBuilder parent, MotcleSyncBuilder child) {
        parent.addChild(child);
        motcleSet.add(child.getIdalpha());
        return this;
    }

    public boolean contains(String idalpha) {
        return motcleSet.contains(idalpha);
    }

    public ThesaurusSync toThesaurusSync() {
        int size = firstLevelList.size();
        MotcleSync[] firstLevel = new MotcleSync[size];
        int p = 0;
        Map<String, MotcleSync> motcleSyncMap = new HashMap<String, MotcleSync>();
        for (MotcleSyncBuilder builder : firstLevelList) {
            MotcleSync motcleSync = builder.toMotcleSync();
            firstLevel[p] = motcleSync;
            p++;
            add(motcleSync, motcleSyncMap);
        }
        return new InternalThesaurusSync(motcleSyncMap, SyncUtils.wrap(motcleSyncMap.values().toArray(new MotcleSync[motcleSyncMap.size()])), SyncUtils.wrap(firstLevel));
    }

    private void add(MotcleSync motcleSync, Map<String, MotcleSync> motcleSyncMap) {
        motcleSyncMap.put(motcleSync.getIdalpha(), motcleSync);
        for (MotcleSync child : motcleSync.getChildList()) {
            add(child, motcleSyncMap);
        }
    }


    private static class InternalThesaurusSync implements ThesaurusSync {

        private final Map<String, MotcleSync> motcleSyncMap;
        private final List<MotcleSync> motcleSyncList;
        private final List<MotcleSync> firstLevelList;

        private InternalThesaurusSync(Map<String, MotcleSync> motcleSyncMap, List<MotcleSync> motcleSyncList, List<MotcleSync> firstLevelList) {
            this.motcleSyncMap = motcleSyncMap;
            this.motcleSyncList = motcleSyncList;
            this.firstLevelList = firstLevelList;
        }

        @Override
        public MotcleSync getMotcleSync(String idalpha) {
            return motcleSyncMap.get(idalpha);
        }

        @Override
        public List<MotcleSync> getMotcleSyncList() {
            return motcleSyncList;
        }

        @Override
        public List<MotcleSync> getFirstLevelList() {
            return firstLevelList;
        }

    }

}
