/* 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.FichothequeConstants;
import net.fichotheque.Subset;
import net.fichotheque.SubsetItem;
import net.fichotheque.SubsetKey;
import net.fichotheque.importation.LiensImport;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.tools.importation.ImportationUtils;
import net.fichotheque.tools.importation.LiensImportBuilder;
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 LiensImportDOMReader {

    private final Fichotheque fichotheque;
    private final LiensImportBuilder liensImportBuilder;
    private final String type;

    public LiensImportDOMReader(Fichotheque fichotheque, LiensImportBuilder liensImportBuilder, String type) {
        this.fichotheque = fichotheque;
        this.liensImportBuilder = liensImportBuilder;
        this.type = type;
    }

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

    public static LiensImportDOMReader init(Fichotheque fichotheque, LiensImportBuilder liensImportBuilder, String type) {
        return new LiensImportDOMReader(fichotheque, liensImportBuilder, type);
    }


    private class IncludeKeyConsumer implements Consumer<Element> {


        private IncludeKeyConsumer() {
        }

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

                        }
                    }
                    break;
            }
        }

    }


    private class LienConsumer implements Consumer<Element> {

        private final boolean replace;

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

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "lien":
                    LiensImport.LienImport lienImport = null;
                    IncludeKey originIncludeKey = null;
                    Subset subset = null;
                    String includeKeyString = element.getAttribute("include-key");
                    if (includeKeyString.isEmpty()) {
                        includeKeyString = element.getAttribute("origin");
                    }
                    if (!includeKeyString.isEmpty()) {
                        try {
                            originIncludeKey = IncludeKey.parse(includeKeyString);
                            subset = fichotheque.getSubset(originIncludeKey.getSubsetKey());
                        } catch (ParseException pe) {
                            return;
                        }
                    } else {
                        try {
                            SubsetKey subsetKey = SubsetKey.parse(element.getAttribute("subset"));
                            subset = fichotheque.getSubset(subsetKey);
                            if (!subsetKey.isCorpusSubset()) {
                                originIncludeKey = IncludeKey.newInstance(subsetKey);
                            }
                        } 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);
                            SubsetItem subsetItem = subset.getSubsetItemById(id);
                            if (subsetItem != null) {
                                if (originIncludeKey != null) {
                                    lienImport = ImportationUtils.toLienImport(originIncludeKey, subsetItem, weight);
                                } else {
                                    lienImport = ImportationUtils.toLiageLienImport(subsetItem, weight);
                                }
                            }
                        } catch (NumberFormatException nfe) {
                        }
                    } else if (subset instanceof Thesaurus) {
                        Thesaurus thesaurus = (Thesaurus) subset;
                        String idalpha = element.getAttribute("idalpha");
                        if (!idalpha.isEmpty()) {
                            lienImport = ImportationUtils.toLienImport(originIncludeKey, thesaurus, idalpha, weight);
                        } else {
                            try {
                                Lang lang = Lang.parse(element.getAttribute("lang"));
                                CleanedString labelString = CleanedString.newInstance(element.getAttribute("label"));
                                if (labelString != null) {
                                    lienImport = ImportationUtils.toLienImport(originIncludeKey, thesaurus, LabelUtils.toLabel(lang, labelString), weight);
                                }
                            } catch (ParseException lie) {
                            }
                        }
                    }
                    if (lienImport != null) {
                        if (replace) {
                            liensImportBuilder.addReplaceLienImport(lienImport);
                        } else {
                            liensImportBuilder.addAppendLienImport(lienImport);
                        }
                    }
                    break;

            }
        }

    }

}
