/* 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 java.text.ParseException;
import net.fichotheque.ExistingIdException;
import net.fichotheque.FichothequeEditor;
import net.fichotheque.croisement.CroisementEditor;
import net.fichotheque.importation.ParentChange;
import net.fichotheque.importation.ThesaurusImport;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.ParentRecursivityException;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.ThesaurusEditor;
import net.fichotheque.tools.FichothequeTools;
import net.fichotheque.tools.thesaurus.ThesaurusTools;
import net.fichotheque.utils.ThesaurusUtils;
import net.mapeadores.util.localisation.Langs;


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

    private ThesaurusImportEngine() {
    }

    public static void runThesaurusImport(EditSession editSession, BdfParameters bdfParameters, ThesaurusImport thesaurusImport) {
        switch (thesaurusImport.getType()) {
            case ThesaurusImport.EDIT_TYPE:
                runEdit(editSession, bdfParameters, thesaurusImport);
                break;
            case ThesaurusImport.REMOVE_TYPE:
                runRemove(editSession, thesaurusImport);
                break;
            case ThesaurusImport.MERGE_TYPE:
                runMerge(editSession, thesaurusImport);
                break;
            case ThesaurusImport.MOVE_TYPE:
                runMove(editSession, thesaurusImport);
                break;
        }
    }

    private static void runEdit(EditSession editSession, BdfParameters bdfParameters, ThesaurusImport thesaurusImport) {
        EditEngine editEngine = new EditEngine(editSession.getFichothequeEditor(), thesaurusImport.getThesaurus(), bdfParameters.getPermissionSummary());
        for (ThesaurusImport.MotcleImport motcleImport : thesaurusImport.getMotcleImportList()) {
            if (motcleImport instanceof ThesaurusImport.EditMotcleImport) {
                editEngine.edit((ThesaurusImport.EditMotcleImport) motcleImport);
            }

        }
    }

    private static void runRemove(EditSession editSession, ThesaurusImport thesaurusImport) {
        Thesaurus thesaurus = thesaurusImport.getThesaurus();
        FichothequeEditor fichothequeEditor = editSession.getFichothequeEditor();
        int resultCount = 0;
        for (ThesaurusImport.MotcleImport motcleImport : thesaurusImport.getMotcleImportList()) {
            Motcle motcle = thesaurus.getMotcleById(motcleImport.getMotcleId());
            if (motcle != null) {
                boolean done = FichothequeTools.remove(fichothequeEditor, motcle);
                if (done) {
                    resultCount++;
                }
            }
        }
    }

    private static void runMerge(EditSession editSession, ThesaurusImport thesaurusImport) {
        Thesaurus thesaurus = thesaurusImport.getThesaurus();
        FichothequeEditor fichothequeEditor = editSession.getFichothequeEditor();
        int resultCount = 0;
        for (ThesaurusImport.MotcleImport motcleImport : thesaurusImport.getMotcleImportList()) {
            ThesaurusImport.MergeMotcleImport mergeMotcleImport = (ThesaurusImport.MergeMotcleImport) motcleImport;
            Motcle motcle = thesaurus.getMotcleById(motcleImport.getMotcleId());
            if (motcle != null) {
                try {
                    Langs langs = editSession.getBdfServer().getThesaurusLangChecker().getAuthorizedLangs(mergeMotcleImport.getDestinationMotcle().getThesaurus());
                    ThesaurusTools.merge(fichothequeEditor, motcle, mergeMotcleImport.getDestinationMotcle(), langs);
                    resultCount++;
                } catch (ParentRecursivityException pre) {
                }
            }
        }
    }

    private static void runMove(EditSession editSession, ThesaurusImport thesaurusImport) {
        Thesaurus thesaurus = thesaurusImport.getThesaurus();
        FichothequeEditor fichothequeEditor = editSession.getFichothequeEditor();
        Thesaurus destinationThesaurus = thesaurusImport.getDestinationThesaurus();
        Langs langs = editSession.getBdfServer().getThesaurusLangChecker().getAuthorizedLangs(destinationThesaurus);
        for (ThesaurusImport.MotcleImport motcleImport : thesaurusImport.getMotcleImportList()) {
            Motcle motcle = thesaurus.getMotcleById(motcleImport.getMotcleId());
            if (motcle != null) {
                ThesaurusTools.move(fichothequeEditor, motcle, destinationThesaurus, langs);
            }
        }
    }


    private static class EditEngine {

        private final FichothequeEditor fichothequeEditor;
        private final Thesaurus thesaurus;
        private final ThesaurusEditor thesaurusEditor;
        private final PermissionSummary permissionSummary;
        private final boolean withIdalpha;

        private EditEngine(FichothequeEditor fichothequeEditor, Thesaurus thesaurus, PermissionSummary permissionSummary) {
            this.fichothequeEditor = fichothequeEditor;
            this.thesaurus = thesaurus;
            this.thesaurusEditor = fichothequeEditor.getThesaurusEditor(thesaurus);
            this.permissionSummary = permissionSummary;
            this.withIdalpha = thesaurus.isIdalphaType();
        }

        private void edit(ThesaurusImport.EditMotcleImport motcleImport) {
            Motcle motcle = null;
            int id = motcleImport.getMotcleId();
            if (id > 0) {
                motcle = thesaurus.getMotcleById(id);
            }
            String newIdalpha = motcleImport.getNewIdalpha();
            if (motcle == null) {
                if (withIdalpha) {
                    if (newIdalpha == null) {
                        return;
                    }
                } else {
                    newIdalpha = null;
                }
                try {
                    motcle = thesaurusEditor.createMotcle(id, newIdalpha);
                } catch (ExistingIdException | ParseException eie) {
                }
            } else {
                if ((withIdalpha) && (newIdalpha != null)) {
                    try {
                        thesaurusEditor.setIdalpha(motcle, newIdalpha);
                    } catch (ExistingIdException | ParseException eie) {
                    }
                }
            }
            if (motcle != null) {
                edit(motcle, motcleImport);
            }
        }

        private void edit(Motcle motcle, ThesaurusImport.EditMotcleImport motcleImport) {
            ThesaurusUtils.changeMotcleLabels(thesaurusEditor, motcle, motcleImport.getLabelChange());
            fichothequeEditor.changeAttributes(motcle, motcleImport.getAttributeChange());
            String newStatus = motcleImport.getNewStatus();
            if (newStatus != null) {
                thesaurusEditor.setStatus(motcle, newStatus);
            }
            CroisementEditor croisementEditor = fichothequeEditor.getCroisementEditor();
            LiensImportEngine.run(croisementEditor, motcle, motcleImport.getLiensImport(), permissionSummary);
            ParentChange parentChange = motcleImport.getParentChange();
            if (parentChange != null) {
                if (parentChange instanceof ParentChange.Thesaurus) {
                    try {
                        thesaurusEditor.setParent(motcle, null);
                    } catch (ParentRecursivityException pre) {
                    }
                } else {
                    Motcle parentMotcle = null;
                    if (parentChange instanceof ParentChange.Id) {
                        parentMotcle = thesaurus.getMotcleById(((ParentChange.Id) parentChange).getParentId());
                    } else if (parentChange instanceof ParentChange.Idalpha) {
                        parentMotcle = thesaurus.getMotcleByIdalpha(((ParentChange.Idalpha) parentChange).getParentIdalpha());
                    }
                    if (parentMotcle != null) {
                        try {
                            thesaurusEditor.setParent(motcle, parentMotcle);
                        } catch (ParentRecursivityException pre) {
                        }
                    }
                }
            }
        }

    }

}
