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

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.users.BdfUser;
import fr.exemole.bdfserver.tools.BdfURI;
import fr.exemole.bdfserver.tools.docstream.DocStreamFactory;
import fr.exemole.bdfserver.tools.instruction.BdfInstructionUtils;
import fr.exemole.bdfserver.tools.users.BdfUserUtils;
import java.net.URI;
import net.mapeadores.util.io.DocStream;
import net.mapeadores.util.localisation.MessageLocalisation;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.servlets.ResponseHandler;
import net.mapeadores.util.servlets.exceptions.ForbiddenException;
import net.mapeadores.util.servlets.exceptions.NotFoundException;
import net.mapeadores.util.servlets.handlers.DocStreamResponseHandler;
import net.mapeadores.util.servlets.handlers.ResponseHandlerFactory;


/**
 *
 * @author Vincent Calame
 */
public class StreamInstruction implements BdfInstruction {

    private final static short MANDATORY_ADMIN = -1;
    private final String rootDir;
    private final String filePath;
    private final BdfServer bdfServer;
    private final RequestMap requestMap;
    private final short userNeed;

    public StreamInstruction(BdfServer bdfServer, RequestMap requestMap, String rootDir, String filePath) {
        this.bdfServer = bdfServer;
        this.rootDir = rootDir;
        this.filePath = filePath;
        this.requestMap = requestMap;
        this.userNeed = getBdfUserNeed(rootDir, filePath);
    }

    @Override
    public short getBdfUserNeed() {
        if (userNeed == MANDATORY_ADMIN) {
            return BdfInstructionConstants.MANDATORY_BDFUSER;
        } else {
            return userNeed;
        }
    }

    @Override
    public ResponseHandler runInstruction(BdfUser bdfUser) {
        if (userNeed == MANDATORY_ADMIN) {
            if (!BdfUserUtils.isAdmin(bdfServer, bdfUser)) {
                throw new ForbiddenException();
            }
        }
        URI uri = BdfURI.toAbsoluteBdfURI(rootDir + "/" + filePath);
        if (uri == null) {
            throw new NotFoundException();
        }
        try {
            DocStream docStream = DocStreamFactory.parseDocStream(bdfServer, uri);
            if (docStream != null) {
                return new DocStreamResponseHandler(docStream);
            } else {
                throw new NotFoundException();
            }
        } catch (ErrorMessageException eme) {
            MessageLocalisation messageLocalisation = BdfInstructionUtils.getMessageLocalisation(requestMap, bdfServer, bdfUser);
            return ResponseHandlerFactory.getHtmlInstance(messageLocalisation, eme.getErrorMessage());
        }
    }

    private static short getBdfUserNeed(String rootDir, String filePath) {
        switch (rootDir) {
            case "dyn":
            case "inc":
                return MANDATORY_ADMIN;
            case GetConstants.TRANSFORMATIONS_ROOT:
            case "transformation":
            case GetConstants.TABLEEXPORT_ROOT:
            case GetConstants.BALAYAGECONTENTS_ROOT:
            case "balayage":
            case GetConstants.ILLUSTRATIONS_ROOT:
                return BdfInstructionConstants.MANDATORY_BDFUSER;
            case "xml-pack":
                int idx = filePath.indexOf('/');
                if (idx == -1) {
                    return BdfInstructionConstants.IF_ANY_BDFUSER;
                } else {
                    return getBdfUserNeed(filePath.substring(0, idx), filePath.substring(idx + 1));
                }
            case "output":
                if (filePath.startsWith("pub/")) {
                    return BdfInstructionConstants.IF_ANY_BDFUSER;
                } else {
                    return BdfInstructionConstants.MANDATORY_BDFUSER;
                }
            case "dyn-pub":
                return BdfInstructionConstants.NONE_BDFUSER;
            default:
                if (filePath.endsWith(".ini")) {
                    return MANDATORY_ADMIN;
                } else if (filePath.contains("/private/")) {
                    return BdfInstructionConstants.MANDATORY_BDFUSER;
                } else {
                    return BdfInstructionConstants.IF_ANY_BDFUSER;
                }
        }
    }

}
