/* BdfServer - Copyright (c) 2008-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.tools.ui.dom;

import fr.exemole.bdfserver.api.ui.CommentUi;
import fr.exemole.bdfserver.api.ui.DataUi;
import fr.exemole.bdfserver.api.ui.FieldUi;
import fr.exemole.bdfserver.api.ui.IncludeUi;
import fr.exemole.bdfserver.tools.ui.UiComponentsBuilder;
import fr.exemole.bdfserver.tools.ui.components.UiDOMUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import net.mapeadores.util.html.HtmlCleaner;
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 UiComponentsDOMReader {

    private final UiComponentsBuilder uiComponentsBuilder;
    private final HtmlCleaner htmlCleaner;
    private final MessageHandler messageHandler;
    private final Map<String, CommentUi> commentUiMap = new HashMap<String, CommentUi>();

    public UiComponentsDOMReader(UiComponentsBuilder uiComponentsBuilder, HtmlCleaner htmlCleaner, MessageHandler messageHandler) {
        this.uiComponentsBuilder = uiComponentsBuilder;
        this.messageHandler = messageHandler;
        this.htmlCleaner = htmlCleaner;
    }

    public void readUiComponents(Element element) {
        DOMUtils.readChildren(element, new FirstStepConsumer());
        DOMUtils.readChildren(element, new SecondStepConsumer());
    }


    private class FirstStepConsumer implements Consumer<Element> {

        private FirstStepConsumer() {

        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("metadata")) {
                DOMUtils.readChildren(element, new MetadataConsumer());
            }
        }

    }


    private class SecondStepConsumer implements Consumer<Element> {

        private SecondStepConsumer() {

        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "metadata":
                    break;
                case "comment": {
                    CommentUi commentUi = UiDOMUtils.readCommentUi(element, htmlCleaner, messageHandler, "comment");
                    if (commentUi != null) {
                        CommentUi existingCommentUi = commentUiMap.get(commentUi.getCommentName());
                        if (existingCommentUi != null) {
                            uiComponentsBuilder.addUiComponent(existingCommentUi);
                        } else {
                            uiComponentsBuilder.addUiComponent(commentUi);
                        }
                    }
                    break;
                }
                case "field-ui": {
                    FieldUi fieldUi = UiDOMUtils.readFieldUi(element, messageHandler, "field-ui");
                    if (fieldUi != null) {
                        uiComponentsBuilder.addUiComponent(fieldUi);
                    }
                    break;
                }
                case "subset-ui": {
                    IncludeUi includeUi = UiDOMUtils.readSubsetIncludeUi(element, messageHandler, "subset-ui");
                    if (includeUi != null) {
                        uiComponentsBuilder.addUiComponent(includeUi);
                    }
                    break;
                }
                case "special-ui": {
                    IncludeUi includeUi = UiDOMUtils.readSpecialIncludeUi(element, messageHandler, "special-ui");
                    if (includeUi != null) {
                        uiComponentsBuilder.addUiComponent(includeUi);
                    }
                    break;
                }
                case "data-ui": {
                    DataUi dataUi = UiDOMUtils.readDataUi(element, messageHandler, "data-ui");
                    if (dataUi != null) {
                        uiComponentsBuilder.addUiComponent(dataUi);
                    }
                    break;
                }
                default: {
                    DomMessages.unknownTagWarning(messageHandler, tagName);
                }
            }
        }

    }


    private class MetadataConsumer implements Consumer<Element> {

        private MetadataConsumer() {

        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("comment-def")) {
                CommentUi commentUi = UiDOMUtils.readCommentUi(element, htmlCleaner, messageHandler, "comment-def");
                if (commentUi != null) {
                    commentUiMap.put(commentUi.getCommentName(), commentUi);
                }
            } else {
                DomMessages.unknownTagWarning(messageHandler, tagName);
            }
        }

    }

}
