/* BdfServer - Copyright (c) 2023 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 fr.exemole.bdfserver.impl;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.managers.SelectionManager;
import fr.exemole.bdfserver.api.storage.SelectionStorage;
import fr.exemole.bdfserver.api.users.BdfUser;
import fr.exemole.bdfserver.tools.users.BdfUserUtils;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
import java.util.RandomAccess;
import java.util.SortedMap;
import java.util.TreeMap;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.selection.FicheQuery;
import net.fichotheque.selection.FichothequeQueries;
import net.fichotheque.selection.SelectionDef;


/**
 *
 * @author Vincent Calame
 */
class SelectionManagerImpl implements SelectionManager {

    private final static List<SelectionDef> EMPTY_LIST = Collections.emptyList();
    private final BdfServer bdfServer;
    private final SelectionStorage selectionStorage;
    private final SortedMap<String, SelectionDef> selectionDefMap = new TreeMap<String, SelectionDef>();
    private List<SelectionDef> selectionDefList = EMPTY_LIST;

    SelectionManagerImpl(BdfServer bdfServer, SelectionStorage selectionStorage) {
        this.bdfServer = bdfServer;
        this.selectionStorage = selectionStorage;
    }

    synchronized void check(List<SelectionDef> selectionDefList) {
        selectionDefMap.clear();
        for (SelectionDef scrutariExportDef : selectionDefList) {
            selectionDefMap.put(scrutariExportDef.getName(), scrutariExportDef);
        }
        updateList();
    }

    @Override
    public List<SelectionDef> getSelectionDefList() {
        return selectionDefList;
    }

    @Override
    public SelectionDef getSelectionDef(String name) {
        return selectionDefMap.get(name);
    }

    @Override
    public synchronized void putSelectionDef(SelectionDef selectionDef) {
        String name = selectionDef.getName();
        selectionDefMap.put(name, selectionDef);
        updateList();
        selectionStorage.saveSelectionDef(selectionDef);
    }

    @Override
    public synchronized void removeSelectionDef(String name) {
        boolean here = selectionDefMap.containsKey(name);
        if (!here) {
            return;
        }
        selectionDefMap.remove(name);
        selectionStorage.removeSelectionDef(name);
        updateList();
    }

    @Override
    public void updateFicheSelection(BdfUser bdfUser) {
        ((BdfUserImpl) bdfUser).updateFicheSelection(bdfServer, BdfUserUtils.getCurrentSortType(bdfServer, bdfUser));
    }

    @Override
    public void setFicheSelection(BdfUser bdfUser, FicheQuery ficheQuery, String sortType) {
        ((BdfUserImpl) bdfUser).setFicheSelection(bdfServer, ficheQuery, sortType);
    }

    @Override
    public void setFicheSelection(BdfUser bdfUser, FichothequeQueries fichothequeQueries, String sortType) {
        ((BdfUserImpl) bdfUser).setFicheSelection(bdfServer, fichothequeQueries, sortType);
    }

    @Override
    public void setFicheSelection(BdfUser bdfUser, String selectionDefName, String sortType) {
        ((BdfUserImpl) bdfUser).setFicheSelection(bdfServer, selectionDefName, sortType);
    }

    @Override
    public void setCustomSelectedFiches(BdfUser bdfUser, Fiches fiches) {
        ((BdfUserImpl) bdfUser).setSelectedFiches(fiches);
    }

    private void updateList() {
        this.selectionDefList = new SelectionDefList(selectionDefMap.values().toArray(new SelectionDef[selectionDefMap.size()]));
    }


    private static class SelectionDefList extends AbstractList<SelectionDef> implements RandomAccess {

        private final SelectionDef[] array;

        private SelectionDefList(SelectionDef[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public SelectionDef get(int index) {
            return array[index];
        }

    }

}
