/* BdfServer - Copyright (c) 2008-2022 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.oldversions;

import fr.exemole.bdfserver.api.BdfServerEditor;
import fr.exemole.bdfserver.api.managers.PermissionManager;
import fr.exemole.bdfserver.api.roles.Role;
import java.text.ParseException;
import java.util.function.Consumer;
import net.fichotheque.Fichotheque;
import net.fichotheque.SubsetKey;
import net.fichotheque.sphere.Redacteur;
import net.fichotheque.sphere.Sphere;
import net.mapeadores.util.logging.MessageHandler;
import net.mapeadores.util.xml.DOMUtils;
import net.mapeadores.util.xml.DomMessages;
import org.w3c.dom.Element;


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

    private final MessageHandler messageHandler;
    private BdfServerEditor bdfServerEditor;
    private Fichotheque fichotheque;
    private PermissionManager permissionManager;

    public PermissionManagerDOMReader(MessageHandler messageHandler) {
        this.messageHandler = messageHandler;
    }

    public void readPermissionManager(BdfServerEditor bdfServerEditor, Element element) {
        this.bdfServerEditor = bdfServerEditor;
        this.fichotheque = bdfServerEditor.getBdfServer().getFichotheque();
        this.permissionManager = bdfServerEditor.getBdfServer().getPermissionManager();
        DOMUtils.readChildren(element, new RootConsumer());
    }


    private class RootConsumer implements Consumer<Element> {

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("admin")) {
                DOMUtils.readChildren(element, new AdminConsumer());
            } else if (tagName.equals("role")) {
                String roleName = element.getAttribute("name");
                if (roleName.length() > 0) {
                    Role role = permissionManager.getRole(roleName);
                    if (role != null) {
                        RoleConsumer roleHandler = new RoleConsumer(role);
                        DOMUtils.readChildren(element, roleHandler);
                    } else {
                        DomMessages.wrongAttributeValue(messageHandler, "role", "name", roleName);
                    }
                } else {
                    DomMessages.emptyAttribute(messageHandler, "role", "name");
                }
            } else {
                DomMessages.unknownTagWarning(messageHandler, tagName);
            }
        }

    }


    private class AdminConsumer implements Consumer<Element> {

        private AdminConsumer() {
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("redacteur")) {
                Redacteur redacteur = getRedacteur(element);
                if (redacteur != null) {
                    bdfServerEditor.setAdmin(redacteur.getGlobalId(), true);
                }
            } else {
                DomMessages.unknownTagWarning(messageHandler, tagName);
            }
        }

    }


    private class RoleConsumer implements Consumer<Element> {

        private final Role role;

        private RoleConsumer(Role role) {
            this.role = role;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("redacteur")) {
                Redacteur redacteur = getRedacteur(element);
                if (redacteur != null) {
                    bdfServerEditor.link(redacteur, role);
                }
            } else {
                DomMessages.unknownTagWarning(messageHandler, tagName);
            }
        }

    }

    private Redacteur getRedacteur(Element element) {
        String sphereString = element.getAttribute("sphere");
        try {
            SubsetKey sphereKey = SubsetKey.parse(SubsetKey.CATEGORY_SPHERE, sphereString);
            Sphere sphere = (Sphere) fichotheque.getSubset(sphereKey);
            if (sphere != null) {
                String idString = element.getAttribute("id");
                if (idString.length() == 0) {
                    idString = element.getAttribute("idsph");
                }
                if (idString.length() > 0) {
                    try {
                        int id = Integer.parseInt(idString);
                        return sphere.getRedacteurById(id);
                    } catch (NumberFormatException nfe) {
                    }
                } else {
                    String loginString = element.getAttribute("idsphere");
                    if (loginString.length() > 0) {
                        return sphere.getRedacteurByLogin(loginString);
                    }
                }
            }
        } catch (ParseException pe) {
        }
        return null;
    }

}
