/* BdfServer_HtmlProducers - Copyright (c) 2012-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.htmlproducers.edition;

import fr.exemole.bdfserver.api.ficheform.FormElementProvider;
import fr.exemole.bdfserver.api.instruction.BdfInstructionConstants;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.instruction.OutputParameters;
import fr.exemole.bdfserver.api.instruction.PermissionException;
import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.api.interaction.domains.EditionDomain;
import fr.exemole.bdfserver.api.namespaces.CommandSpace;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.tools.ficheform.FicheFormParametersBuilder;
import fr.exemole.bdfserver.tools.ficheform.FicheFormUtils;
import fr.exemole.bdfserver.tools.ficheform.FormElementProviderFactory;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import fr.exemole.bdfserver.tools.instruction.BdfInstructionUtils;
import fr.exemole.bdfserver.tools.instruction.OutputRequestHandler;
import fr.exemole.bdfserver.tools.roles.PermissionCheck;
import net.fichotheque.SubsetItem;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.pointeurs.FichePointeur;
import net.fichotheque.tools.duplication.DuplicationFilter;
import net.fichotheque.tools.duplication.DuplicationFilterParser;
import net.fichotheque.tools.duplication.DuplicationUtils;
import net.fichotheque.utils.pointeurs.PointeurFactory;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.logging.ErrorMessageException;


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

    private EditionHtmlProducerFactory() {
    }

    public static BdfServerHtmlProducer getHtmlProducer(OutputParameters parameters) throws ErrorMessageException {
        OutputRequestHandler requestHandler = OutputRequestHandler.init(parameters);
        String page = parameters.getOutput();
        switch (page) {
            case EditionDomain.ZOOMEDIT_PAGE: {
                String appelant = requestHandler.getMandatoryParameter("appelant");
                String corpusName = requestHandler.getMandatoryParameter("corpus");
                return new ZoomEditHtmlProducer(parameters, appelant, corpusName);
            }
            case EditionDomain.FICHE_RESULT_PAGE: {
                FicheResultHandler ficheResultHandler = FicheResultHandler.build(requestHandler.getFicheMeta(), requestHandler);
                return new FicheResultHtmlProducer(parameters, ficheResultHandler);
            }
            case EditionDomain.FICHE_INDEXATION_PAGE: {
                FicheMeta ficheMeta = requestHandler.getFicheMeta();
                parameters.checkSubsetAdmin(ficheMeta.getCorpus());
                FichePointeur fichePointeur = PointeurFactory.newFichePointeur(ficheMeta.getCorpus()).setCurrentFicheMeta(ficheMeta);
                FormElementProvider formElementProvider = FormElementProviderFactory.newInstance(FicheFormParametersBuilder.build(parameters)
                        .toFicheFormParameters());
                return new FicheIndexationHtmlProducer(parameters, fichePointeur, formElementProvider);
            }
            case EditionDomain.FICHE_CREATION_PAGE: {
                Corpus corpus = requestHandler.getCorpus();
                checkFicheCreate(parameters, corpus);
                String prefill = requestHandler.getTrimedParameter(EditionDomain.PREFILL_PARAMNAME);
                boolean isDuplicate = (prefill.equals("duplicate"));
                if (corpus.getMasterSubset() != null) {
                    if (isDuplicate) {
                        throw BdfErrors.error("_ error.unsupported.satellitecorpus", corpus.getSubsetName());
                    } else {
                        return new SatelliteFicheCreationHtmlProducer(parameters, corpus);
                    }
                } else {
                    FichePointeur fichePointeur = PointeurFactory.newFichePointeur(corpus, true);
                    if (isDuplicate) {
                        FicheMeta ficheMeta = requestHandler.getFicheMeta();
                        fichePointeur.setCurrentSubsetItem(ficheMeta);
                        fichePointeur = filterDuplicateFichePointeur(corpus, fichePointeur);
                    }
                    FormElementProvider formElementProvider = FormElementProviderFactory.newInstance(parameters);
                    FicheFormHtmlProducer ficheFormHtmlProducer = FicheFormHtmlProducer.newCreationInstance(parameters, fichePointeur, formElementProvider);
                    checkOptions(ficheFormHtmlProducer, requestHandler);
                    return ficheFormHtmlProducer;
                }
            }
            case EditionDomain.FICHE_CHANGE_PAGE: {
                Corpus corpus = requestHandler.getCorpus();
                FichePointeur fichePointeur = PointeurFactory.newFichePointeur(corpus, true);
                int id = -1;
                FicheMeta ficheMeta = (FicheMeta) parameters.getResultObject(BdfInstructionConstants.FICHEMETA_OBJ);
                if (ficheMeta == null) {
                    id = requestHandler.getMandatoryId();
                    ficheMeta = corpus.getFicheMetaById(id);
                }
                if (ficheMeta != null) {
                    parameters.checkWrite(ficheMeta);
                    fichePointeur.setCurrentSubsetItem(ficheMeta);
                    FormElementProvider formElementProvider = FormElementProviderFactory.newInstance(parameters);
                    FicheFormHtmlProducer ficheFormHtmlProducer = FicheFormHtmlProducer.newChangeInstance(parameters, fichePointeur, formElementProvider);
                    checkOptions(ficheFormHtmlProducer, requestHandler);
                    return ficheFormHtmlProducer;
                } else {
                    checkFicheCreate(parameters, corpus);
                    SubsetItem masterSubsetItem = BdfInstructionUtils.checkMasterSubsetItem(corpus, id, parameters.getBdfUser());
                    boolean force = requestHandler.isTrue(EditionDomain.FORCE_PARAMNAME);
                    if (!force) {
                        return new CreationConfirmHtmlProducer(parameters, corpus, id, masterSubsetItem);
                    }
                    FormElementProvider formElementProvider = FormElementProviderFactory.newInstance(FicheFormUtils.initFicheFormParametersBuilder(parameters).setMasterSubsetItem(masterSubsetItem).toFicheFormParameters());
                    FicheFormHtmlProducer ficheFormHtmlProducer;
                    if (masterSubsetItem != null) {
                        ficheFormHtmlProducer = FicheFormHtmlProducer.newCreationInstance(parameters, fichePointeur, masterSubsetItem, formElementProvider);
                    } else {
                        ficheFormHtmlProducer = FicheFormHtmlProducer.newCreationInstance(parameters, fichePointeur, id, formElementProvider);
                    }
                    checkOptions(ficheFormHtmlProducer, requestHandler);
                    return ficheFormHtmlProducer;
                }
            }
            case EditionDomain.SECTIONPREVIEW_PAGE: {
                Corpus corpus = requestHandler.getCorpus();
                return new SectionPreviewHtmlProducer(parameters, corpus);
            }
            default:
                return null;
        }
    }

    private static void checkOptions(FicheFormHtmlProducer ficheFormHtmlProducer, OutputRequestHandler requestHandler) throws ErrorMessageException {
        String resultPage = requestHandler.getTrimedParameter(InteractionConstants.PAGE_RESULT_PARAMNAME);
        if (!resultPage.isEmpty()) {
            ficheFormHtmlProducer.setFicheResultPage(resultPage);
        }
        String resultPageOptions = requestHandler.getTrimedParameter(InteractionConstants.PAGE_RESULT_OPTIONS_PARAMNAME);
        if (!resultPageOptions.isEmpty()) {
            ficheFormHtmlProducer.setResultPageOptions(resultPageOptions);
        }
        ficheFormHtmlProducer.setGotoAtStart(requestHandler.getTrimedParameter(InteractionConstants.GOTO_PARAMNAME));
    }

    private static void checkFicheCreate(BdfParameters bdfParameters, Corpus corpus) throws PermissionException {
        PermissionCheck.checkFicheCreate(bdfParameters.getPermissionSummary(), corpus);
    }

    private static FichePointeur filterDuplicateFichePointeur(Corpus corpus, FichePointeur originalFichePointeur) {
        Attribute excludeAttribute = corpus.getCorpusMetadata().getAttributes().getAttribute(CommandSpace.DUPLICATION_EXCLUDE_KEY);
        if (excludeAttribute != null) {
            DuplicationFilter duplicationFilter = DuplicationFilterParser.parseExclude(excludeAttribute);
            return DuplicationUtils.getFilteredFichePointeur(originalFichePointeur, duplicationFilter);
        } else {
            return originalFichePointeur;
        }
    }

}
