/* BdfServer_Get - Copyright (c) 2011-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.get;

import fr.exemole.bdfserver.api.BdfExtensionReference;
import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.instruction.BdfInstruction;
import fr.exemole.bdfserver.api.instruction.BdfInstructionConstants;
import fr.exemole.bdfserver.api.interaction.GetConstants;
import fr.exemole.bdfserver.api.managers.ExtensionManager;
import fr.exemole.bdfserver.api.providers.BdfInstructionProvider;
import fr.exemole.bdfserver.api.users.BdfUser;
import fr.exemole.bdfserver.get.instructions.AccessInstruction;
import fr.exemole.bdfserver.get.instructions.AdminInstruction;
import fr.exemole.bdfserver.get.instructions.BalayagesInstruction;
import fr.exemole.bdfserver.get.instructions.DiagramsInstruction;
import fr.exemole.bdfserver.get.instructions.DocumentsInstruction;
import fr.exemole.bdfserver.get.instructions.FichesInstruction;
import fr.exemole.bdfserver.get.instructions.MotclesInstruction;
import fr.exemole.bdfserver.get.instructions.StreamInstruction;
import fr.exemole.bdfserver.get.instructions.TablesInstruction;
import fr.exemole.bdfserver.get.instructions.UsersInstruction;
import fr.exemole.bdfserver.tools.instruction.BdfInstructionUtils;
import fr.exemole.bdfserver.tools.instruction.RedirectBdfInstruction;
import net.mapeadores.util.localisation.MessageLocalisation;
import net.mapeadores.util.logging.CommandMessage;
import net.mapeadores.util.logging.LogUtils;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.servlets.ResponseHandler;
import net.mapeadores.util.servlets.handlers.ResponseHandlerFactory;


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

    private GetInstructionFactory() {
    }

    public static BdfInstruction getBdfInstruction(BdfServer bdfServer, RequestMap requestMap, String dirName, String filePath) {
        switch (dirName) {
            case GetConstants.ADMIN_ROOT:
                return new AdminInstruction(bdfServer, filePath);
            case GetConstants.API_ROOT:
                return AccessInstruction.build(bdfServer, requestMap, filePath);
            case GetConstants.BALAYAGES_ROOT:
                return new BalayagesInstruction(bdfServer, filePath);
            case GetConstants.DIAGRAMS_ROOT:
                return new DiagramsInstruction(bdfServer, filePath);
            case GetConstants.DOCUMENTS_ROOT:
                return DocumentsInstruction.build(bdfServer, filePath);
            case GetConstants.EXTENSION_ROOT: {
                int idxext = filePath.indexOf('/');
                if (idxext == -1) {
                    return new RedirectBdfInstruction(filePath + "/");
                }
                String extensionName = filePath.substring(0, idxext);
                String extensionPath = filePath.substring(idxext);
                ExtensionManager manager = bdfServer.getExtensionManager();
                BdfExtensionReference bdfExtensionReference = manager.getBdfExtensionReference(extensionName);
                if (bdfExtensionReference == null) {
                    if (filePath.endsWith("/")) {
                        return getExtensionError(bdfServer, requestMap, extensionName);
                    } else {
                        return null;
                    }
                }
                BdfInstructionProvider bdfInstructionProvider = (BdfInstructionProvider) bdfExtensionReference.getImplementation(BdfInstructionProvider.class);
                if (bdfInstructionProvider == null) {
                    return null;
                } else {
                    return bdfInstructionProvider.getBdfInstruction(bdfServer, extensionPath, requestMap);
                }
            }
            case GetConstants.FICHES_ROOT:
                return new FichesInstruction(bdfServer, requestMap, filePath);
            case GetConstants.MOTCLES_ROOT:
            case "motscles":
                return new MotclesInstruction(bdfServer, filePath, requestMap);
            case GetConstants.TABLES_ROOT:
                return new TablesInstruction(bdfServer, filePath, requestMap);
            case GetConstants.USERS_ROOT:
            case "redacteurs":
                return new UsersInstruction(bdfServer, filePath);
            default:
                return new StreamInstruction(bdfServer, requestMap, dirName, filePath);
        }
    }

    private static BdfInstruction getExtensionError(BdfServer bdfServer, RequestMap requestMap, String extensionName) {
        return new ErrorBdfInstruction(bdfServer, requestMap, LogUtils.error("_ error.unknown.extension", extensionName));
    }


    private static class ErrorBdfInstruction implements BdfInstruction {

        private final BdfServer bdfServer;
        private final RequestMap requestMap;
        private final CommandMessage[] errorMessages;

        private ErrorBdfInstruction(BdfServer bdfServer, RequestMap requestMap, CommandMessage... errorMessages) {
            this.bdfServer = bdfServer;
            this.requestMap = requestMap;
            this.errorMessages = errorMessages;
        }

        @Override
        public short getBdfUserNeed() {
            return BdfInstructionConstants.IF_ANY_BDFUSER;
        }

        @Override
        public ResponseHandler runInstruction(BdfUser bdfUser) {
            MessageLocalisation messageLocalisation = BdfInstructionUtils.getMessageLocalisation(requestMap, bdfServer, bdfUser);
            return ResponseHandlerFactory.getInstance(messageLocalisation, requestMap, errorMessages);
        }

    }

}
