/* 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.dom;

import java.text.ParseException;
import java.util.function.Consumer;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.thesaurus.sync.MotcleSync;
import net.fichotheque.tools.thesaurus.sync.MotcleSyncBuilder;
import net.fichotheque.tools.thesaurus.sync.ThesaurusSyncBuilder;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.logging.MessageHandler;
import net.mapeadores.util.text.LabelChangeBuilder;
import net.mapeadores.util.text.LabelUtils;
import net.mapeadores.util.xml.DOMUtils;
import net.mapeadores.util.xml.DomMessages;
import org.w3c.dom.Element;


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

    private final ThesaurusSyncBuilder thesaurusSyncBuilder;
    private final MessageHandler messageHandler;

    public KeywordsDOMReader(ThesaurusSyncBuilder thesaurusSync, MessageHandler messageHandler) {
        this.thesaurusSyncBuilder = thesaurusSync;
        this.messageHandler = messageHandler;
    }

    public KeywordsDOMReader read(Element element) {
        DOMUtils.readChildren(element, new RootConsumer());
        return this;
    }

    public static KeywordsDOMReader init(ThesaurusSyncBuilder thesaurusSync, MessageHandler messageHandler) {
        return new KeywordsDOMReader(thesaurusSync, messageHandler);
    }


    private class RootConsumer implements Consumer<Element> {

        private RootConsumer() {

        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "keyword":
                    initMotcleSync(element, FichothequeConstants.ACTIVE_STATUS);
                    break;
                case "group":
                    initMotcleSync(element, FichothequeConstants.GROUP_STATUS);
                    break;
            }
        }

        private void initMotcleSync(Element element, String status) {
            String idalpha = element.getAttribute("id");
            if (thesaurusSyncBuilder.contains(idalpha)) {
                return;
            }
            MotcleSyncBuilder motcleSyncBuilder = MotcleSyncBuilder.init(idalpha)
                    .setStatus(status);
            DOMUtils.readChildren(element, new KeywordConsumer(motcleSyncBuilder));
            thesaurusSyncBuilder.addFirstLevel(motcleSyncBuilder);
        }

    }


    private class KeywordConsumer implements Consumer<Element> {

        private final MotcleSyncBuilder motcleSyncBuilder;

        private KeywordConsumer(MotcleSyncBuilder motcleSyncBuilder) {
            this.motcleSyncBuilder = motcleSyncBuilder;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "label":
                    LabelChangeBuilder labelChangeBuilder = motcleSyncBuilder.getLabelChangeBuilder();
                    try {
                        LabelUtils.readLabel(element, labelChangeBuilder);
                    } catch (ParseException pe) {
                        DomMessages.wrongLangAttribute(messageHandler, tagName, element.getAttribute("xml:lang"));
                    }
                    break;
                case "attr":
                    AttributeUtils.readAttrElement(motcleSyncBuilder.getAttributeChangeBuilder(), element);
                    break;
                case "keyword":
                    initChild(element, FichothequeConstants.ACTIVE_STATUS);
                    break;
                case "group":
                    initChild(element, FichothequeConstants.GROUP_STATUS);
                    break;
            }
        }

        private MotcleSync initChild(Element element, String status) {
            String idalpha = element.getAttribute("id");
            if (thesaurusSyncBuilder.contains(idalpha)) {
                return null;
            }
            MotcleSyncBuilder childBuilder = MotcleSyncBuilder.init(idalpha)
                    .setStatus(status);
            DOMUtils.readChildren(element, new KeywordConsumer(childBuilder));
            MotcleSync motcleSync = motcleSyncBuilder.toMotcleSync();
            thesaurusSyncBuilder.addChild(motcleSyncBuilder, childBuilder);
            return motcleSync;
        }

    }

}
