/* BdfServer - Copyright (c) 2010-2026 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.instruction;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.EditSession;
import fr.exemole.bdfserver.api.instruction.BdfCommand;
import fr.exemole.bdfserver.api.instruction.BdfCommandResult;
import fr.exemole.bdfserver.api.instruction.BdfInstructionConstants;
import fr.exemole.bdfserver.api.instruction.PermissionException;
import fr.exemole.bdfserver.api.users.BdfUser;
import net.fichotheque.Fichotheque;
import net.fichotheque.Subset;
import net.fichotheque.utils.EditOriginUtils;
import net.mapeadores.util.logging.CommandMessage;
import net.mapeadores.util.logging.CommandMessageBuilder;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.logging.LogUtils;
import net.mapeadores.util.request.RequestMap;


/**
 *
 * @author Vincent Calame
 */
public abstract class AbstractBdfCommand implements BdfCommand, BdfInstructionConstants {

    private final static CommandMessage TEST_DONE_MESSAGE = LogUtils.done("_ done.global.test");
    private final RequestMap requestMap;
    protected final BdfServer bdfServer;
    protected final Fichotheque fichotheque;
    protected BdfUser bdfUser;
    protected RequestHandler requestHandler;
    private CommandMessage commandMessage;
    private BdfCommandResultBuilder commandResultBuilder;

    public AbstractBdfCommand(BdfServer bdfServer, RequestMap requestMap) {
        this.bdfServer = bdfServer;
        this.requestMap = requestMap;
        this.fichotheque = bdfServer.getFichotheque();
    }

    @Override
    public CommandMessage testCommand(BdfUser bdfUser) {
        this.bdfUser = bdfUser;
        this.requestHandler = new RequestHandler(bdfServer, bdfUser, requestMap);
        try {
            checkParameters();
            return TEST_DONE_MESSAGE;
        } catch (ErrorMessageException eme) {
            return eme.getErrorMessage();
        }
    }

    @Override
    public BdfCommandResult doCommand(BdfUser bdfUser) {
        this.bdfUser = bdfUser;
        this.requestHandler = new RequestHandler(bdfServer, bdfUser, requestMap);
        commandMessage = null;
        commandResultBuilder = new BdfCommandResultBuilder();
        boolean canDo = false;
        try {
            checkParameters();
            canDo = true;
        } catch (ErrorMessageException eme) {
            commandMessage = eme.getErrorMessage();
        }
        if (canDo) {
            try {
                doCommand();
            } catch (ErrorMessageException eme) {
                commandMessage = eme.getErrorMessage();
            }
        }
        if (commandMessage != null) {
            commandResultBuilder.setCommandMessage(commandMessage);
        }
        return commandResultBuilder.toBdfCommandResult();
    }

    public PermissionChecker getPermissionChecker() {
        return requestHandler.getPermissionChecker();
    }

    public void checkFichothequeAdmin() throws PermissionException {
        requestHandler.getPermissionChecker().checkFichothequeAdmin();
    }

    public void checkSubsetAdmin(Subset subset) throws PermissionException {
        requestHandler.getPermissionChecker().checkSubsetAdmin(subset);
    }

    public String getMandatory(String paramName) throws ErrorMessageException {
        return requestHandler.getMandatoryParameter(paramName);
    }

    public boolean checkConfirmation() {
        return BdfInstructionUtils.checkConfirmation(requestMap, bdfServer);
    }

    protected abstract void checkParameters() throws ErrorMessageException;

    protected abstract void doCommand() throws ErrorMessageException;

    protected void putResultObject(String name, Object obj) {
        if (commandResultBuilder != null) {
            commandResultBuilder.putResultObject(name, obj);
        }
    }

    protected void setDone(String doneMessageKey, Object... messageValues) {
        this.commandMessage = CommandMessageBuilder.init()
                .setDone(doneMessageKey, messageValues)
                .toCommandMessage();
    }

    protected void setCommandMessage(CommandMessage commandMessage) {
        this.commandMessage = commandMessage;
    }

    protected EditSession startEditSession(String domain, String commandName) {
        return startEditSession(domain + "/" + commandName);
    }

    protected EditSession startEditSession(String source) {
        if (bdfUser != null) {
            return bdfServer.initEditSession(bdfUser, source);
        } else {
            return bdfServer.initEditSession(EditOriginUtils.newEditOrigin(source));
        }
    }

}
