/* FichothequeLib_Tools - Copyright (c) 2013-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 net.fichotheque.tools.importation.dom;

import java.text.ParseException;
import java.util.function.Consumer;
import net.fichotheque.Fichotheque;
import net.fichotheque.Subset;
import net.fichotheque.importation.TiesImport;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.tools.importation.ImportationUtils;
import net.fichotheque.tools.importation.TiesImportBuilder;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.text.CleanedString;
import net.mapeadores.util.text.LabelUtils;
import net.mapeadores.util.xml.DOMUtils;
import org.w3c.dom.Element;


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

    private final Fichotheque fichotheque;
    private final TiesImportBuilder tiesImportBuilder;
    private final String type;

    public TiesImportDOMReader(Fichotheque fichotheque, TiesImportBuilder tiesImportBuilder, String type) {
        this.fichotheque = fichotheque;
        this.tiesImportBuilder = tiesImportBuilder;
        this.type = type;
    }

    public TiesImportDOMReader read(Element element) {
        switch (type) {
            case "replace":
                DOMUtils.readChildren(element, new TieConsumer(true));
                break;
            case "append":
                DOMUtils.readChildren(element, new TieConsumer(false));
                break;
            case "remove":
                DOMUtils.readChildren(element, new RemoveConsumer());
                break;
        }
        return this;
    }

    public static TiesImportDOMReader init(Fichotheque fichotheque, TiesImportBuilder tiesImportBuilder, String type) {
        return new TiesImportDOMReader(fichotheque, tiesImportBuilder, type);
    }


    private class RemoveConsumer implements Consumer<Element> {


        private RemoveConsumer() {
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "include-key":
                    String value = DOMUtils.readSimpleElement(element);
                    try {
                        IncludeKey includeKey = IncludeKey.parse(value);
                        tiesImportBuilder.addRemovedIncludeKey(includeKey);
                    } catch (ParseException pe) {

                    }
                    break;
            }
        }

    }


    private class TieConsumer implements Consumer<Element> {

        private final boolean replace;

        private TieConsumer(boolean replace) {
            this.replace = replace;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "tie":
                case "lien":
                    TiesImport.TieImport tieImport = null;
                    IncludeKey includeKey;
                    Subset subset;
                    String includeKeyString = element.getAttribute("include-key");
                    if (includeKeyString.isEmpty()) {
                        includeKeyString = element.getAttribute("origin");
                    }
                    try {
                        includeKey = IncludeKey.parse(includeKeyString);
                        subset = fichotheque.getSubset(includeKey.getSubsetKey());
                    } catch (ParseException pe) {
                        return;
                    }
                    if (subset == null) {
                        return;
                    }
                    int weight = 1;
                    String weightString = element.getAttribute("weight");
                    if (weightString.isEmpty()) {
                        weightString = element.getAttribute("poids");
                    }
                    if (!weightString.isEmpty()) {
                        try {
                            weight = Integer.parseInt(weightString);
                            if (weight < 1) {
                                weight = 1;
                            }
                        } catch (NumberFormatException nfe) {
                        }
                    }
                    String idString = element.getAttribute("id");
                    if (idString.length() > 0) {
                        try {
                            int id = Integer.parseInt(idString);
                            tieImport = ImportationUtils.toTieImport(includeKey, subset, id, weight);
                        } catch (NumberFormatException nfe) {
                        }
                    } else if (subset instanceof Thesaurus) {
                        Thesaurus thesaurus = (Thesaurus) subset;
                        String idalpha = element.getAttribute("idalpha");
                        if (!idalpha.isEmpty()) {
                            tieImport = ImportationUtils.toTieImport(includeKey, thesaurus, idalpha, weight);
                        } else {
                            try {
                                Lang lang = Lang.parse(element.getAttribute("lang"));
                                CleanedString labelString = CleanedString.newInstance(element.getAttribute("label"));
                                if (labelString != null) {
                                    tieImport = ImportationUtils.toTieImport(includeKey, thesaurus, LabelUtils.toLabel(lang, labelString), weight);
                                }
                            } catch (ParseException lie) {
                            }
                        }
                    }
                    if (tieImport != null) {
                        if (replace) {
                            tiesImportBuilder.addReplaceTieImport(tieImport);
                        } else {
                            tiesImportBuilder.addAppendTieImport(tieImport);
                        }
                    }
                    break;

            }
        }

    }

}
