/* 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.AccessManager;
import fr.exemole.bdfserver.api.storage.AccessStorage;
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.exportation.access.AccessDef;


/**
 *
 * @author Vincent Calame
 */
class AccessManagerImpl implements AccessManager {

    private final static List<AccessDef> EMPTY_LIST = Collections.emptyList();
    private final BdfServer bdfServer;
    private final AccessStorage accessStorage;
    private final SortedMap<String, AccessDef> accessDefMap = new TreeMap<String, AccessDef>();
    private List<AccessDef> accessDefList = EMPTY_LIST;

    AccessManagerImpl(BdfServer bdfServer, AccessStorage accessStorage) {
        this.bdfServer = bdfServer;
        this.accessStorage = accessStorage;
    }

    synchronized void check(List<AccessDef> accessDefList) {
        accessDefMap.clear();
        for (AccessDef scrutariExportDef : accessDefList) {
            accessDefMap.put(scrutariExportDef.getName(), scrutariExportDef);
        }
        updateList();
    }

    @Override
    public List<AccessDef> getAccessDefList() {
        return accessDefList;
    }

    @Override
    public AccessDef getAccessDef(String name) {
        return accessDefMap.get(name);
    }

    @Override
    public synchronized void putAccessDef(AccessDef accessDef) {
        String name = accessDef.getName();
        accessDefMap.put(name, accessDef);
        updateList();
        accessStorage.saveAccessDef(accessDef);
    }

    @Override
    public synchronized void removeAccessDef(String name) {
        boolean here = accessDefMap.containsKey(name);
        if (!here) {
            return;
        }
        accessDefMap.remove(name);
        accessStorage.removeAccessDef(name);
        updateList();
    }

    private void updateList() {
        this.accessDefList = new AccessDefList(accessDefMap.values().toArray(new AccessDef[accessDefMap.size()]));
    }


    private static class AccessDefList extends AbstractList<AccessDef> implements RandomAccess {

        private final AccessDef[] array;

        private AccessDefList(AccessDef[] array) {
            this.array = array;
        }

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

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

    }

}
