/* BdfServer_DirectoryStorage - Copyright (c) 2010-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 fr.exemole.bdfserver.storage.directory.oldversions;

import java.text.ParseException;
import net.fichotheque.ExistingIdException;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.ParentRecursivityException;
import net.fichotheque.thesaurus.ThesaurusEditor;
import net.fichotheque.thesaurus.metadata.ThesaurusMetadata;
import net.fichotheque.thesaurus.metadata.ThesaurusMetadataEditor;
import net.fichotheque.tools.dom.FichothequeDOMUtils;
import net.fichotheque.utils.ThesaurusUtils;
import net.mapeadores.util.attr.AttributeUtils;
import net.mapeadores.util.attr.AttributesBuilder;
import net.mapeadores.util.exceptions.ImplementationException;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.LangsUtils;
import net.mapeadores.util.logging.MessageHandler;
import net.mapeadores.util.text.Label;
import net.mapeadores.util.text.LabelUtils;
import net.mapeadores.util.xml.DomMessages;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * Correspond à un format XML supprimé à la révision 1590.
 *
 * @author Vincent Calame
 */
public class ThesaurusDOMReader {

    private ThesaurusEditor thesaurusEditor;
    private ThesaurusMetadataEditor thesaurusMetadataEditor;
    private final MessageHandler messageHandler;

    public ThesaurusDOMReader(ThesaurusEditor thesaurusEditor, MessageHandler messageHandler) {
        this.messageHandler = messageHandler;
        this.thesaurusEditor = thesaurusEditor;
        this.thesaurusMetadataEditor = thesaurusEditor.getThesaurusMetadataEditor();
    }

    public void setThesaurusEditor(ThesaurusEditor thesaurusEditor) {
        this.thesaurusEditor = thesaurusEditor;
        this.thesaurusMetadataEditor = thesaurusEditor.getThesaurusMetadataEditor();
    }

    public static short getThesaurusType(Element element_xml) {
        String typeString = element_xml.getAttribute("thesaurus-type");
        return ThesaurusUtils.thesaurusTypeToShort(typeString);
    }

    public void fillThesaurus(Element element_xml) {
        NodeList liste = element_xml.getChildNodes();
        boolean metadone = false;
        for (int i = 0; i < liste.getLength(); i++) {
            Node nd = liste.item(i);
            if (nd.getNodeType() == Node.ELEMENT_NODE) {
                Element el = (Element) nd;
                String tagname = el.getTagName();
                if ((!metadone) && (tagname.equals("metadata"))) {
                    metadone = true;
                    fillMetadata(el);
                } else if (tagname.equals("motcle")) {
                    addMotcle(el, null);
                } else {
                    DomMessages.unknownTagWarning(messageHandler, tagname);
                }
            }
        }
    }

    private void fillMetadata(Element element_xml) {
        ThesaurusMetadata metadata = (ThesaurusMetadata) thesaurusMetadataEditor.getMetadata();
        AttributesBuilder attributesBuilder = new AttributesBuilder();
        if (metadata.getThesaurusType() != ThesaurusMetadata.BABELIEN_TYPE) {
            String langsString = element_xml.getAttribute("thesaurus-langs");
            if (langsString.length() == 0) {
                DomMessages.emptyAttribute(messageHandler, element_xml.getTagName(), "thesaurus-langs");
            } else {
                Langs langs = LangsUtils.toCleanLangs(langsString);
                if (langs.size() > 0) {
                    thesaurusMetadataEditor.setAuthorizedLangs(langs);
                } else {
                    DomMessages.wrongAttributeValue(messageHandler, element_xml.getTagName(), "thesaurus-langs", langsString);
                }
            }
        }
        NodeList liste = element_xml.getChildNodes();
        for (int i = 0; i < liste.getLength(); i++) {
            Node nd = liste.item(i);
            if (nd.getNodeType() == Node.ELEMENT_NODE) {
                Element el = (Element) nd;
                String tagname = el.getTagName();
                if (tagname.equals("intitule")) {
                    FichothequeDOMUtils.readIntitule(el, thesaurusMetadataEditor, messageHandler, "thesaurus");
                } else if (tagname.equals("attr")) {
                    AttributeUtils.readAttrElement(attributesBuilder, el, messageHandler, tagname);
                } else {
                    DomMessages.unknownTagWarning(messageHandler, tagname);
                }
            }
        }
        thesaurusEditor.getFichothequeEditor().putAttributes(metadata, attributesBuilder.toAttributes());
    }

    private void addMotcle(Element element_xml, Motcle parent) {
        String idString = element_xml.getAttribute("id");
        if (idString.length() == 0) {
            idString = element_xml.getAttribute("idths");
        }
        if (idString.length() == 0) {
            DomMessages.emptyAttribute(messageHandler, element_xml.getTagName(), "id");
            return;
        }
        int motcleid;
        try {
            motcleid = Integer.parseInt(idString);
        } catch (NumberFormatException nfe) {
            DomMessages.wrongIntegerAttributeValue(messageHandler, element_xml.getTagName(), "id", idString);
            return;
        }
        String idalpha = null;
        if (thesaurusEditor.getThesaurus().isIdalphaType()) {
            idalpha = element_xml.getAttribute("idalpha");
            if (idalpha.length() == 0) {
                DomMessages.emptyAttribute(messageHandler, element_xml.getTagName(), "idalpha");
                return;
            }
        }
        Motcle motcle;
        try {
            motcle = thesaurusEditor.createMotcle(motcleid, idalpha);
        } catch (ExistingIdException eie) {
            messageHandler.addMessage(FichothequeConstants.SEVERE_FICHOTHEQUE, "_ error.existing.idalpha", idalpha);
            return;
        } catch (ParseException pe) {
            DomMessages.wrongAttributeValue(messageHandler, element_xml.getTagName(), "idalpha", idalpha);
            return;
        }
        if (parent != null) {
            try {
                thesaurusEditor.setParent(motcle, parent);
            } catch (ParentRecursivityException pre) {
                throw new ImplementationException(pre);
            }
        }
        NodeList liste = element_xml.getChildNodes();
        for (int i = 0; i < liste.getLength(); i++) {
            Node nd = liste.item(i);
            if (nd.getNodeType() == Node.ELEMENT_NODE) {
                Element el = (Element) nd;
                String tagname = el.getTagName();
                if (tagname.equals("lib")) {
                    try {
                        Label label = LabelUtils.readLabel(el);
                        if (label != null) {
                            thesaurusEditor.putLabel(motcle, label);
                        }
                    } catch (ParseException e) {
                        DomMessages.wrongLangAttribute(messageHandler, "lib", el.getAttribute("xml:lang"));
                    }
                } else if (tagname.equals("motcle")) {
                    addMotcle(el, motcle);
                } else {
                    DomMessages.unknownTagWarning(messageHandler, tagname);
                }
            }
        }
    }

}
