/* 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.util.function.Consumer;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.importation.CorpusImport;
import net.fichotheque.importation.ImportationContext;
import net.fichotheque.tools.importation.corpus.CorpusImportBuilder;
import net.fichotheque.tools.importation.corpus.EditCorpusImportBuilder;
import net.fichotheque.tools.importation.corpus.EditFicheImportBuilder;
import net.fichotheque.tools.importation.corpus.RemoveCorpusImportBuilder;
import net.mapeadores.util.exceptions.SwitchException;
import net.mapeadores.util.xml.DOMUtils;
import org.w3c.dom.Element;


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

    private final Corpus corpus;
    private final CorpusImportBuilder corpusImportBuilder;
    private final ImportationContext importationContext;

    public CorpusImportDOMReader(CorpusImportBuilder corpusImportBuilder, ImportationContext importationContext) {
        this.corpusImportBuilder = corpusImportBuilder;
        this.corpus = corpusImportBuilder.getCorpus();
        this.importationContext = importationContext;
    }

    public CorpusImportDOMReader read(Element element) {
        Consumer<Element> elementConsumer;
        String type = corpusImportBuilder.getType();
        switch (type) {
            case CorpusImport.EDIT_TYPE:
                elementConsumer = new EditConsumer((EditCorpusImportBuilder) corpusImportBuilder);
                break;
            case CorpusImport.REMOVE_TYPE:
                elementConsumer = new RemoveConsumer((RemoveCorpusImportBuilder) corpusImportBuilder);
                break;
            default:
                throw new SwitchException("Unknown type: " + type);
        }
        DOMUtils.readChildren(element, elementConsumer);
        return this;
    }

    public static CorpusImportDOMReader init(CorpusImportBuilder corpusImportBuilder, ImportationContext importationContext) {
        return new CorpusImportDOMReader(corpusImportBuilder, importationContext);
    }


    private class EditConsumer implements Consumer<Element> {

        private final EditCorpusImportBuilder editCorpusImportBuilder;

        private EditConsumer(EditCorpusImportBuilder editCorpusImportBuilder) {
            this.editCorpusImportBuilder = editCorpusImportBuilder;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "ficheimport":
                    String idString = element.getAttribute("id");
                    if (idString.isEmpty()) {
                        readCreation(-1, element);
                    } else {
                        try {
                            int id = Integer.parseInt(idString);
                            FicheMeta ficheMeta = corpus.getFicheMetaById(id);
                            if (ficheMeta != null) {
                                readChange(ficheMeta, element);
                            } else {
                                readCreation(id, element);
                            }
                        } catch (NumberFormatException nfe) {
                        }
                    }
                    break;
            }
        }

        private void readChange(FicheMeta ficheMeta, Element element) {
            EditFicheImportBuilder ficheImportBuilder = editCorpusImportBuilder.getEditFicheImportBuilder(ficheMeta);
            FicheImportDOMReader.init(ficheImportBuilder, corpus.getFichotheque(), importationContext).read(element);
        }

        private void readCreation(int newId, Element element) {
            EditFicheImportBuilder ficheImportBuilder = editCorpusImportBuilder.getEditFicheImportBuilder(newId);
            FicheImportDOMReader.init(ficheImportBuilder, corpus.getFichotheque(), importationContext).read(element);

        }

    }


    private class RemoveConsumer implements Consumer<Element> {

        private final RemoveCorpusImportBuilder removeCorpusImportBuilder;

        private RemoveConsumer(RemoveCorpusImportBuilder removeCorpusImportBuilder) {
            this.removeCorpusImportBuilder = removeCorpusImportBuilder;
        }

        @Override
        public void accept(Element element) {
            String tagName = element.getTagName();
            switch (tagName) {
                case "ficheimport":
                    String idString = element.getAttribute("id");
                    try {
                        int id = Integer.parseInt(idString);
                        FicheMeta ficheMeta = corpus.getFicheMetaById(id);
                        if (ficheMeta != null) {
                            removeCorpusImportBuilder.add(ficheMeta);
                        }
                    } catch (NumberFormatException nfe) {
                    }
                    break;
            }
        }

    }

}
