/* 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.parsers;

import java.text.ParseException;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheChange;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.Fiche;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.CorpusMetadata;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.corpus.metadata.SubfieldKey;
import net.fichotheque.tools.corpus.FicheChangeBuilder;
import net.fichotheque.utils.CorpusUtils;
import net.mapeadores.util.request.RequestMap;


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

    public final static short NONE_TYPE = 0;
    public final static short REPLACE_TYPE = 1;
    public final static short UPDATE_TYPE = 2;

    private FicheParseEngine() {
    }

    public static Fiche run(FicheParser ficheParser, FicheMeta ficheMeta, RequestMap requestMap, short type) {
        Corpus corpus = ficheMeta.getCorpus();
        CorpusMetadata corpusMetadata = corpus.getCorpusMetadata();
        FicheChangeBuilder ficheChangeBuilder = new FicheChangeBuilder();
        FicheParser.Buffer buffer = ficheParser.getBuffer(ficheChangeBuilder);
        for (String paramName : requestMap.getParameterNameSet()) {
            boolean subfieldDone = parseSubfield(buffer, corpusMetadata, paramName, requestMap);
            if (!subfieldDone) {
                parseCorpusField(buffer, corpusMetadata, paramName, requestMap);
            }
        }
        buffer.flushParsedSubfields();
        FicheChange ficheChange = ficheChangeBuilder.toFicheChange();
        if (type == REPLACE_TYPE) {
            return CorpusUtils.toFiche(ficheChange);
        } else {
            Fiche originalFiche = ficheMeta.getCorpus().getFiche(ficheMeta);
            CorpusUtils.updateFiche(originalFiche, ficheChange);
            return originalFiche;
        }
    }

    private static boolean parseCorpusField(FicheParser.Buffer buffer, CorpusMetadata corpusMetadata, String paramName, RequestMap requestMap) {
        try {
            FieldKey fieldKey = FieldKey.parse(paramName);
            CorpusField corpusField = corpusMetadata.getCorpusField(fieldKey);
            if (corpusField != null) {
                String[] paramValues = requestMap.getParameterValues(paramName);
                for (String value : paramValues) {
                    buffer.parseCorpusField(corpusField, value);
                }
            }
            return true;
        } catch (ParseException pe) {
            return false;
        }
    }

    private static boolean parseSubfield(FicheParser.Buffer buffer, CorpusMetadata corpusMetadata, String paramName, RequestMap requestMap) {
        try {
            SubfieldKey subfieldKey = SubfieldKey.parse(paramName);
            FieldKey fieldKey = subfieldKey.getFieldKey();
            CorpusField corpusField = corpusMetadata.getCorpusField(fieldKey);
            if (corpusField != null) {
                String value = requestMap.getParameter(paramName);
                buffer.parseSubfield(corpusField, subfieldKey, value);
            }
            return true;
        } catch (ParseException pe) {
            return false;
        }
    }

}
