/* BdfServer_Multi - Copyright (c) 2015-2023 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.multi;

import fr.exemole.bdfserver.conf.ConfConstants;
import fr.exemole.bdfserver.multi.api.Multi;
import fr.exemole.bdfserver.multi.commands.AbstractMultiCommand;
import fr.exemole.bdfserver.multi.commands.MultiMetadataCommand;
import fr.exemole.bdfserver.multi.commands.central.AddToFichothequeCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralEmailChangeCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralPasswordChangeCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralPersonChangeCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralSphereMetadataCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralStatusChangeCommand;
import fr.exemole.bdfserver.multi.commands.central.CentralUserCreationCommand;
import fr.exemole.bdfserver.multi.commands.central.CopyFromFichothequeCommand;
import fr.exemole.bdfserver.multi.commands.central.FichothequeSphereCreateCommand;
import fr.exemole.bdfserver.multi.commands.central.StatusInFichothequeChangeCommand;
import fr.exemole.bdfserver.multi.commands.fichotheque.FichothequeActionCommand;
import fr.exemole.bdfserver.multi.commands.fichotheque.FichothequeCreationCommand;
import fr.exemole.bdfserver.multi.commands.fichotheque.FichothequeDuplicationCommand;
import fr.exemole.bdfserver.multi.commands.fichotheque.FichothequeInitCommand;
import fr.exemole.bdfserver.multi.commands.personmanager.PersonAddCommand;
import fr.exemole.bdfserver.multi.commands.personmanager.PersonChangeCommand;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import net.mapeadores.util.ini.IniParser;
import net.mapeadores.util.logging.CommandMessage;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.logging.LogUtils;
import net.mapeadores.util.request.RequestConstants;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.request.RequestMapBuilder;
import net.mapeadores.util.text.RelativePath;


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

    private MultiCommands() {

    }

    public static CommandMessage run(Multi multi, RequestMap requestMap) {
        String cmd = requestMap.getParameter(RequestConstants.COMMAND_PARAMETER);
        if (cmd == null) {
            return null;
        }
        AbstractMultiCommand command = getCommand(multi, requestMap, cmd);
        if (command == null) {
            return LogUtils.error("_ error.unknown.parametervalue", "cmd", cmd);
        } else {
            try {
                return command.doCommand();
            } catch (ErrorMessageException eme) {
                return eme.getErrorMessage();
            }
        }
    }

    public static CommandMessage runFromFile(Multi multi, RelativePath relativePath) {
        Path filePath = multi.getMultiDirs().resolveSubPath(ConfConstants.VAR_RUN, relativePath);
        if (!Files.exists(filePath)) {
            return LogUtils.error("_ error.unknown.file", relativePath.toString());
        }
        if (Files.isDirectory(filePath)) {
            return LogUtils.error("_ error.unsupported.directory", relativePath.toString());
        }
        RequestMapBuilder requestMapBuilder = new RequestMapBuilder();
        try (InputStream is = Files.newInputStream(filePath)) {
            IniParser.parseIni(is, (key, value) -> {
                requestMapBuilder.addParameter(key, value);
            });
        } catch (IOException ioe) {
            return LogUtils.error("_ error.exception.io_read", ioe.getLocalizedMessage());
        }
        try {
            Files.delete(filePath);
        } catch (IOException ioe) {
            return LogUtils.error("_ error.exception.io_delete", ioe.getLocalizedMessage());
        }
        return run(multi, requestMapBuilder.toRequestMap());
    }

    private static AbstractMultiCommand getCommand(Multi multi, RequestMap requestMap, String cmd) {
        switch (cmd) {
            case FichothequeCreationCommand.COMMAND_NAME: {
                return new FichothequeCreationCommand(multi, requestMap);
            }
            case FichothequeDuplicationCommand.COMMAND_NAME: {
                return new FichothequeDuplicationCommand(multi, requestMap);
            }
            case FichothequeInitCommand.COMMAND_NAME: {
                return new FichothequeInitCommand(multi, requestMap);
            }
            case MultiMetadataCommand.COMMAND_NAME: {
                return new MultiMetadataCommand(multi, requestMap);
            }
            case PersonChangeCommand.COMMAND_NAME: {
                return new PersonChangeCommand(multi, requestMap);
            }
            case PersonAddCommand.COMMAND_NAME: {
                return new PersonAddCommand(multi, requestMap);
            }
            case FichothequeActionCommand.COMMAND_NAME: {
                return new FichothequeActionCommand(multi, requestMap);
            }
            case CopyFromFichothequeCommand.COMMAND_NAME: {
                return new CopyFromFichothequeCommand(multi, requestMap);
            }
            case CentralSphereMetadataCommand.COMMAND_NAME: {
                return new CentralSphereMetadataCommand(multi, requestMap);
            }
            case CentralUserCreationCommand.COMMAND_NAME: {
                return new CentralUserCreationCommand(multi, requestMap);
            }
            case CentralPersonChangeCommand.COMMAND_NAME: {
                return new CentralPersonChangeCommand(multi, requestMap);
            }
            case CentralEmailChangeCommand.COMMAND_NAME: {
                return new CentralEmailChangeCommand(multi, requestMap);
            }
            case CentralStatusChangeCommand.COMMAND_NAME: {
                return new CentralStatusChangeCommand(multi, requestMap);
            }
            case CentralPasswordChangeCommand.COMMAND_NAME: {
                return new CentralPasswordChangeCommand(multi, requestMap);
            }
            case AddToFichothequeCommand.COMMAND_NAME: {
                return new AddToFichothequeCommand(multi, requestMap);
            }
            case StatusInFichothequeChangeCommand.COMMAND_NAME: {
                return new StatusInFichothequeChangeCommand(multi, requestMap);
            }
            case FichothequeSphereCreateCommand.COMMAND_NAME: {
                return new FichothequeSphereCreateCommand(multi, requestMap);
            }
            default:
                return null;
        }
    }

}
