/*
 * RESTHeart Security
 * 
 * Copyright (C) SoftInstigate Srl
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.restheart.security.handlers;

import org.restheart.security.handlers.exchange.AbstractExchange;
import org.restheart.security.plugins.PluginsRegistry;

import io.undertow.server.HttpServerExchange;
import java.util.List;
import org.restheart.security.utils.LambdaUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.restheart.security.plugins.RequestInterceptor;

/**
 *
 * @author Andrea Di Cesare {@literal <andrea@softinstigate.com>}
 */
public class RequestInterceptorsExecutor extends PipedHttpHandler {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(RequestInterceptorsExecutor.class);

    /**
     *
     */
    public RequestInterceptorsExecutor() {
        super(null);
    }

    /**
     * @param next
     */
    public RequestInterceptorsExecutor(PipedHttpHandler next) {
        super(next);
    }

    /**
     *
     * @param exchange
     * @throws Exception
     */
    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        List<RequestInterceptor> interceptors = PluginsRegistry
                .getInstance()
                .getRequestInterceptors();

        interceptors.stream()
                .filter(ri -> ri.resolve(exchange))
                .forEachOrdered(ri -> {
                    try {
                        LOGGER.debug("Executing request interceptor {} for {}",
                                ri.getClass().getSimpleName(),
                                exchange.getRequestPath());

                        ri.handleRequest(exchange);
                    } catch (Exception ex) {
                        LOGGER.error("Error executing request interceptor {} for {}",
                                ri.getClass().getSimpleName(),
                                exchange.getRequestPath(),
                                ex);
                        AbstractExchange.setInError(exchange);
                        LambdaUtils.throwsSneakyExcpetion(ex);
                    }
                });

        next(exchange);
    }
}

@@ -851,16 +851,189 @@
 l.List;%0A
+import org.restheart.security.handlers.exchange.ByteArrayResponse;%0Aimport org.restheart.security.plugins.RequestInterceptor;%0Aimport org.restheart.security.utils.HttpStatus;%0A
 import o
@@ -1133,66 +1133,8 @@
 ory;
-%0Aimport org.restheart.security.plugins.RequestInterceptor;
 %0A%0A/*
@@ -1388,24 +1388,89 @@
 or.class);%0A%0A
+    private final ResponseSender sender = new ResponseSender();%0A%0A
     /**%0A    
@@ -2839,24 +2839,519 @@
        %7D);%0A%0A
+        var response = ByteArrayResponse.wrap(exchange);%0A%0A        // if an interceptor sets the response as errored%0A        // stop processing the request and send the response%0A        if (response.isInError()) %7B%0A            // if in error but no status code%0A            // set it to 400 Bad Request%0A            if (response.getStatusCode() %3C 0) %7B%0A                response.setStatusCode(HttpStatus.SC_BAD_REQUEST);%0A            %7D%0A%0A            sender.handleRequest(exchange);%0A        %7D else %7B%0A    
         next
@@ -3358,20 +3358,30 @@
 (exchange);%0A
+        %7D%0A
     %7D%0A%7D%0A

Stop processing request and send the response if an interceptor sets the response as errored