/* BdfServer_DirectoryStorage - Copyright (c) 2022-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 fr.exemole.bdfserver.storage.directory.tools;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.conf.ConfDirs;
import fr.exemole.bdfserver.storage.directory.StorageDirectoryUtils;
import fr.exemole.bdfserver.storage.directory.bdfdata.BdfdataConstants;
import fr.exemole.bdfserver.storage.directory.bdfdata.BdfdataStorageFileCatalog;
import fr.exemole.bdfserver.tools.storage.StorageFile;
import java.util.function.Consumer;
import net.fichotheque.SubsetKey;
import net.fichotheque.sphere.LoginKey;
import net.mapeadores.util.xml.DOMUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import fr.exemole.bdfserver.storage.directory.StorageDirectory;


/**
 *
 * @author Vincent Calame
 */
public final class SphereChecker {

    private SphereChecker() {

    }

    public static boolean containsSphere(SubsetKey sphereKey, ConfDirs confDirs) {
        StorageDirectory bdfdataDirectory = initBdfdataDirectory(confDirs);
        StorageFile storageFile = BdfdataStorageFileCatalog.sphereMetadata(bdfdataDirectory, sphereKey);
        return storageFile.exists();
    }

    public static boolean containsRedacteur(LoginKey loginKey, ConfDirs confDirs) {
        StorageDirectory bdfdataDirectory = initBdfdataDirectory(confDirs);
        SubsetKey sphereKey = loginKey.getSphereKey();
        StorageFile storageFile = BdfdataStorageFileCatalog.sphereList(bdfdataDirectory, sphereKey);
        if (!storageFile.exists()) {
            return false;
        }
        try {
            Document document = storageFile.readDocument();
            return SphereChecker.isHere(document, loginKey.getLogin());
        } catch (BdfStorageException bse) {
            return false;
        }
    }

    private static StorageDirectory initBdfdataDirectory(ConfDirs confDirs) {
        return StorageDirectoryUtils.toStorageDirectory(confDirs, BdfdataConstants.ROOT);
    }

    private static boolean isHere(Document document, String login) {
        try {
            DOMUtils.readChildren(document.getDocumentElement(), new RootConsumer(login));
            return false;
        } catch (FindException fe) {
            return fe.isActive();
        }
    }


    private static class RootConsumer implements Consumer<Element> {

        private final String seekedLogin;

        private RootConsumer(String seekedLogin) {
            this.seekedLogin = seekedLogin;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("redacteur")) {
                String idString = element.getAttribute("id");
                if (idString.length() == 0) {
                    idString = element.getAttribute("idsph");
                }
                if (idString.length() == 0) {
                    return;
                }
                try {
                    Integer.parseInt(idString);
                } catch (NumberFormatException nfe) {
                    return;
                }
                String login = element.getAttribute("login");
                if (login.equals(seekedLogin)) {
                    boolean active = getActive(element);
                    throw new FindException(active);
                }
            }
        }

        private boolean getActive(Element element) {
            boolean active = true;
            String activeString = element.getAttribute("active");
            if (activeString.length() == 0) {
                activeString = element.getAttribute("actif");
            }
            if (activeString.equals("0")) {
                active = false;
            }
            return active;
        }

    }


    private static class FindException extends RuntimeException {

        private final boolean active;

        private FindException(boolean active) {
            this.active = active;
        }

        public boolean isActive() {
            return active;
        }

    }

}
