/* BdfServer_HtmlProducers - 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.htmlproducers.addenda;

import fr.exemole.bdfserver.api.instruction.BdfCommandResult;
import fr.exemole.bdfserver.api.instruction.BdfInstructionConstants;
import fr.exemole.bdfserver.api.instruction.OutputParameters;
import fr.exemole.bdfserver.api.interaction.domains.AddendaDomain;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import fr.exemole.bdfserver.tools.instruction.OutputRequestHandler;
import fr.exemole.bdfserver.tools.roles.PermissionCheck;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.Document;
import net.fichotheque.tools.parsers.DocumentChangeInfo;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.primitives.FileLength;
import net.mapeadores.util.request.RequestMap;


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

    private final static int ADDENDA_ADMIN = 1;
    private final static int ADDENDA_READ = 2;
    private final static int DOCUMENT = 3;

    private AddendaHtmlProducerFactory() {
    }

    public static BdfServerHtmlProducer getHtmlProducer(OutputParameters parameters) throws ErrorMessageException {
        OutputRequestHandler requestHandler = OutputRequestHandler.init(parameters);
        String page = parameters.getOutput();
        RequestMap requestMap = parameters.getRequestMap();
        BdfCommandResult bdfCommandResult = parameters.getBdfCommandResult();
        switch (getPageType(page)) {
            case ADDENDA_ADMIN: {
                Addenda addenda = requestHandler.getAddenda();
                parameters.checkSubsetAdmin(addenda);
                switch (page) {
                    case AddendaDomain.ADDENDA_ADVANCEDCOMMANDS_PAGE: {
                        return new AddendaAdvancedCommandsHtmlProducer(parameters, addenda);
                    }
                    case AddendaDomain.ADDENDA_METADATAFORM_PAGE: {
                        return new AddendaMetadataFormHtmlProducer(parameters, addenda);
                    }
                    default:
                        return null;
                }
            }
            case ADDENDA_READ: {
                Addenda addenda = requestHandler.getAddenda();
                switch (page) {
                    case AddendaDomain.ADDENDA_PAGE: {
                        return new AddendaHtmlProducer(parameters, addenda);
                    }
                    case AddendaDomain.DOCUMENT_CHANGE_PAGE: {
                        String appelant = getAppelant(requestMap);
                        if (bdfCommandResult != null) {
                            DocumentChangeInfo documentChangeInfo = (DocumentChangeInfo) bdfCommandResult.getResultObject(BdfInstructionConstants.DOCUMENTCHANGEINFO_OBJ);
                            String originalName = (String) bdfCommandResult.getResultObject(BdfInstructionConstants.STRING_OBJ);
                            return DocumentChangeHtmlProducer.newDocumentCreate(parameters, appelant, originalName, documentChangeInfo, addenda);
                        }
                        String changeType = requestHandler.getMandatoryParameter("changetype");
                        String changeInfoString = requestMap.getParameter("change");
                        DocumentChangeInfo documentChangeInfo = DocumentChangeInfo.EMPTY;
                        if (changeInfoString != null) {
                            documentChangeInfo = DocumentChangeInfo.parse(changeInfoString);
                        }
                        if (changeType.equals(AddendaDomain.DOCUMENT_CHANGETYPE)) {
                            Document document = requestHandler.getMandatoryDocument();
                            return DocumentChangeHtmlProducer.newDocumentChange(parameters, appelant, document, documentChangeInfo, addenda);
                        } else if (changeType.equals(AddendaDomain.CREATION_CHANGETYPE)) {
                            if ((documentChangeInfo.getNewBasename() == null) || (documentChangeInfo.getTmpFileCount() == 0)) {
                                if (changeInfoString == null) {
                                    throw BdfErrors.emptyMandatoryParameter("change");
                                } else {
                                    throw BdfErrors.wrongParameterValue("change", changeInfoString);
                                }
                            }
                            String originalName = requestMap.getParameter("originalname");
                            return DocumentChangeHtmlProducer.newDocumentCreate(parameters, appelant, originalName, documentChangeInfo, addenda);
                        } else {
                            throw BdfErrors.unknownParameterValue("changetype", changeType);
                        }
                    }
                    case AddendaDomain.DOCUMENT_UPLOAD_NEW_PAGE: {
                        String appelant = getAppelant(requestMap);
                        return DocumentUploadHtmlProducer.newNewUpload(parameters, appelant, addenda);
                    }
                    case AddendaDomain.DOCUMENT_UPLOAD_VERSION_PAGE: {
                        String appelant = getAppelant(requestMap);
                        return DocumentUploadHtmlProducer.newVersionUpload(parameters, appelant, addenda);
                    }
                    default:
                        return null;
                }
            }
            case DOCUMENT: {
                Document document = requestHandler.getDocument();
                switch (page) {
                    case AddendaDomain.DOCUMENT_ADMINFORM_PAGE: {
                        PermissionCheck.checkWrite(parameters.getPermissionSummary(), document);
                        return new DocumentAdminFormHtmlProducer(parameters, document);
                    }
                    case AddendaDomain.DOCUMENT_ADVANCEDCOMMANDS_PAGE: {
                        parameters.checkSubsetAdmin(document.getAddenda());
                        return new DocumentAdvancedCommandsHtmlProducer(parameters, document);
                    }
                    default:
                        return null;
                }
            }
            default:
                switch (page) {
                    case AddendaDomain.ADDENDA_CREATIONFORM_PAGE: {
                        parameters.checkFichothequeAdmin();
                        return new AddendaCreationFormHtmlProducer(parameters);
                    }
                    case AddendaDomain.DOCUMENT_UPLOAD_CONFIRM_PAGE: {
                        String appelant = getAppelant(requestMap);
                        if (bdfCommandResult != null) {
                            DocumentChangeInfo documentChangeInfo = (DocumentChangeInfo) bdfCommandResult.getResultObject(BdfInstructionConstants.DOCUMENTCHANGEINFO_OBJ);
                            FileLength fileLength = (FileLength) bdfCommandResult.getResultObject(BdfInstructionConstants.FILELENGTH_OBJ);
                            return new DocumentUploadConfirmHtmlProducer(parameters, appelant, documentChangeInfo, fileLength);
                        } else {
                            return null;
                        }
                    }
                    default:
                        return null;
                }
        }
    }

    private static int getPageType(String page) {
        switch (page) {
            case AddendaDomain.ADDENDA_ADVANCEDCOMMANDS_PAGE:
            case AddendaDomain.ADDENDA_METADATAFORM_PAGE:
                return ADDENDA_ADMIN;
            case AddendaDomain.ADDENDA_PAGE:
            case AddendaDomain.DOCUMENT_CHANGE_PAGE:
            case AddendaDomain.DOCUMENT_UPLOAD_NEW_PAGE:
            case AddendaDomain.DOCUMENT_UPLOAD_VERSION_PAGE:
                return ADDENDA_READ;
            case AddendaDomain.DOCUMENT_ADMINFORM_PAGE:
            case AddendaDomain.DOCUMENT_ADVANCEDCOMMANDS_PAGE:
                return DOCUMENT;
            default:
                return 0;
        }

    }

    private static String getAppelant(RequestMap requestMap) {
        return requestMap.getParameter("appelant");
    }

}
