/* BdfServer - 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 fr.exemole.bdfserver.tools.importation.engines;

import fr.exemole.bdfserver.api.EditSession;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.tools.instruction.BdfCommandUtils;
import net.fichotheque.ExistingIdException;
import net.fichotheque.FichothequeEditor;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.CorpusEditor;
import net.fichotheque.corpus.FicheChange;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.NoMasterIdException;
import net.fichotheque.corpus.fiche.Fiche;
import net.fichotheque.croisement.CroisementEditor;
import net.fichotheque.importation.CorpusImport;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.tools.FichothequeTools;
import net.fichotheque.tools.corpus.CorpusTools;
import net.fichotheque.tools.corpus.FieldGenerationEngine;
import net.fichotheque.utils.CorpusUtils;
import net.mapeadores.util.primitives.FuzzyDate;


/**
 *
 * @author Vincent Calame
 */
public final class CorpusImportEngine {

    private CorpusImportEngine() {
    }

    public static void runCorpusImport(EditSession editSession, BdfParameters bdfParameters, CorpusImport corpusImport) {
        switch (corpusImport.getType()) {
            case CorpusImport.EDIT_TYPE:
                runEdit(editSession, bdfParameters, corpusImport);
                break;
            case CorpusImport.REMOVE_TYPE:
                runRemove(editSession, corpusImport);
                break;
        }
    }

    private static void runEdit(EditSession editSession, BdfParameters bdfParameters, CorpusImport corpusImport) {
        Corpus corpus = corpusImport.getCorpus();
        EditEngine editEngine = new EditEngine(editSession.getFichothequeEditor(), corpus, BdfCommandUtils.buildEngine(bdfParameters, corpus), bdfParameters.getPermissionSummary());
        for (CorpusImport.FicheImport ficheImport : corpusImport.getFicheImportList()) {
            if (ficheImport instanceof CorpusImport.EditFicheImport) {
                editEngine.edit((CorpusImport.EditFicheImport) ficheImport);
            }
        }
    }

    private static void runRemove(EditSession editSession, CorpusImport corpusImport) {
        Corpus corpus = corpusImport.getCorpus();
        FichothequeEditor fichothequeEditor = editSession.getFichothequeEditor();
        for (CorpusImport.FicheImport ficheImport : corpusImport.getFicheImportList()) {
            FicheMeta ficheMeta = corpus.getFicheMetaById(ficheImport.getFicheId());
            if (ficheMeta != null) {
                FichothequeTools.remove(fichothequeEditor, ficheMeta);
            }
        }
    }


    private static class EditEngine {

        private final FichothequeEditor fichothequeEditor;
        private final Corpus corpus;
        private final CorpusEditor corpusEditor;
        private final CroisementEditor croisementEditor;
        private final FieldGenerationEngine engine;
        private final PermissionSummary permissionSummary;

        private EditEngine(FichothequeEditor fichothequeEditor, Corpus corpus, FieldGenerationEngine engine, PermissionSummary permissionSummary) {
            this.fichothequeEditor = fichothequeEditor;
            this.corpus = corpus;
            this.corpusEditor = fichothequeEditor.getCorpusEditor(corpus);
            this.engine = engine;
            this.croisementEditor = fichothequeEditor.getCroisementEditor();
            this.permissionSummary = permissionSummary;
        }

        private void edit(CorpusImport.EditFicheImport editFicheImport) {
            FicheMeta ficheMeta = null;
            int id = editFicheImport.getFicheId();
            if (id > 0) {
                ficheMeta = corpus.getFicheMetaById(id);
            }
            FuzzyDate creationDate = editFicheImport.getCreationDate();
            FicheChange ficheChange = editFicheImport.getFicheChange();
            if (ficheMeta != null) {
                if (creationDate != null) {
                    corpusEditor.setDate(ficheMeta, creationDate, false);
                }
                if (CorpusUtils.hasChanges(ficheChange)) {
                    Fiche fiche = corpus.getFiche(ficheMeta);
                    CorpusUtils.updateFiche(fiche, ficheChange);
                    CorpusTools.saveFiche(corpusEditor, ficheMeta, fiche, engine, true);
                }
            } else {
                try {
                    ficheMeta = corpusEditor.createFiche(id);
                } catch (ExistingIdException | NoMasterIdException e) {
                    return;
                }
                if (creationDate != null) {
                    corpusEditor.setDate(ficheMeta, creationDate, false);
                    corpusEditor.setDate(ficheMeta, FuzzyDate.current(), true);
                } else {
                    corpusEditor.setDate(ficheMeta, FuzzyDate.current(), false);
                }
                Fiche fiche = new Fiche();
                if (CorpusUtils.hasChanges(ficheChange)) {
                    CorpusUtils.updateFiche(fiche, ficheChange);
                }
                CorpusTools.saveFiche(corpusEditor, ficheMeta, fiche, engine, false);
            }
            fichothequeEditor.changeAttributes(ficheMeta, editFicheImport.getAttributeChange());
            LiensImportEngine.run(croisementEditor, ficheMeta, editFicheImport.getLiensImport(), permissionSummary);
        }

    }

}
