/* UtilLib - Copyright (c) 2019-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 net.mapeadores.util.exec;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import net.mapeadores.util.xml.DOMUtils;
import org.w3c.dom.Element;


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

    private final ArgsDefBuilder argsDefBuilder;

    public ArgsDefDOMReader(ArgsDefBuilder argsDefBuilder) {
        this.argsDefBuilder = argsDefBuilder;
    }

    public void readArgs(Element element) {
        DOMUtils.readChildren(element, new RootConsumer());
    }

    public static void read(ArgsDefBuilder argsDefBuilder, Element rootElement) {
        ArgsDefDOMReader reader = new ArgsDefDOMReader(argsDefBuilder);
        reader.readArgs(rootElement);
    }


    private class RootConsumer implements Consumer<Element> {

        private RootConsumer() {
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("parameter")) {
                String charValue = element.getAttribute("char");
                if (charValue.length() > 0) {
                    char letter = charValue.charAt(0);
                    String titleLocKey = element.getAttribute("lockey");
                    String valueState = element.getAttribute("value");
                    if (valueState.equals("require")) {
                        argsDefBuilder.addParameter(letter, titleLocKey, true);
                    } else if (valueState.equals("list")) {
                        List<String> valueList = new ArrayList<String>();
                        DOMUtils.readChildren(element, new ValueListConsumer(valueList));
                        argsDefBuilder.addParameter(letter, titleLocKey, valueList);
                    } else {
                        argsDefBuilder.addParameter(letter, titleLocKey, false);
                    }
                }
            } else if (tagName.equals("command")) {
                String name = element.getAttribute("name");
                if (name.length() > 0) {
                    CommandDefBuilder commandDefBuilder = CommandDefBuilder.init(name).setTitleLocKey(element.getAttribute("lockey"));
                    DOMUtils.readChildren(element, new CommandConsumer(commandDefBuilder));
                    argsDefBuilder.addCommandDef(commandDefBuilder.toCommandDef());
                }
            }
        }

    }


    private static class ValueListConsumer implements Consumer<Element> {

        private final List<String> valueList;

        private ValueListConsumer(List<String> valueList) {
            this.valueList = valueList;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("value")) {
                valueList.add(element.getAttribute("name"));
            }
        }

    }


    private static class CommandConsumer implements Consumer<Element> {

        private final CommandDefBuilder commandDefBuilder;

        private CommandConsumer(CommandDefBuilder commandDefBuilder) {
            this.commandDefBuilder = commandDefBuilder;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            if (tagName.equals("mandatory")) {
                addUserParameter(element, true);
            } else if (tagName.equals("optional")) {
                addUserParameter(element, false);
            }
        }

        private void addUserParameter(Element element, boolean mandatory) {
            String value = DOMUtils.readSimpleElement(element);
            if (value.length() > 0) {
                commandDefBuilder.addUsedParameter(value.charAt(0), mandatory);
            }
        }

    }

}
