/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * 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 io.gravitee.gateway.reactor.processor;

import io.gravitee.gateway.api.ExecutionContext;
import io.gravitee.gateway.core.processor.Processor;
import io.gravitee.gateway.core.processor.chain.DefaultProcessorChain;
import io.gravitee.gateway.reactor.processor.forward.XForwardForProcessor;
import io.gravitee.gateway.reactor.processor.transaction.TraceContextProcessor;
import io.gravitee.gateway.reactor.processor.transaction.TraceContextProcessorFactory;
import io.gravitee.gateway.reactor.processor.transaction.TransactionProcessorFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author David BRASSELY (david.brassely at graviteesource.com)
 * @author GraviteeSource Team
 */
public class RequestProcessorChainFactory implements InitializingBean {

    @Autowired
    private TransactionProcessorFactory transactionHandlerFactory;

    @Autowired
    private TraceContextProcessorFactory traceContextHandlerFactory;

    @Value("${handlers.request.trace-context.enabled:false}")
    private boolean traceContext;

    private final List<Processor<ExecutionContext>> processors = new ArrayList<>();

    @Override
    public void afterPropertiesSet() throws Exception {
        processors.add(new XForwardForProcessor());
        processors.add(transactionHandlerFactory.create());

        if (traceContext) processors.add(traceContextHandlerFactory.create());
    }

    public Processor<ExecutionContext> create() {
        return new DefaultProcessorChain<>(processors);
    }
}

@@ -820,21 +820,17 @@
 sor.
-chain.Default
+provider.
 Proc
@@ -834,21 +834,24 @@
 rocessor
-Chain
+Provider
 ;%0Aimport
@@ -875,45 +875,107 @@
 way.
-reactor.processor.forward.XForwardFor
+core.processor.provider.ProcessorProviderChain;%0Aimport io.gravitee.gateway.core.processor.provider.
 Proc
@@ -971,32 +971,40 @@
 ovider.Processor
+Supplier
 ;%0Aimport io.grav
@@ -1038,32 +1038,27 @@
 sor.
-transaction.TraceContext
+forward.XForwardFor
 Proc
@@ -1451,33 +1451,8 @@
 st;%0A
-import java.util.Arrays;%0A
 impo
@@ -1937,32 +1937,40 @@
 l List%3CProcessor
+Provider
 %3CExecutionContex
@@ -1974,20 +1974,19 @@
 text
-%3E%3E p
+, P
 rocessor
 s = 
@@ -1981,16 +1981,45 @@
 rocessor
+%3CExecutionContext%3E%3E%3E provider
 s = new 
@@ -2111,29 +2111,28 @@
 %0A        pro
-cesso
+vide
 rs.add(new X
@@ -2130,16 +2130,36 @@
 add(new 
+ProcessorSupplier%3C%3E(
 XForward
@@ -2170,17 +2170,21 @@
 rocessor
-(
+::new
 ));%0A    
@@ -2190,28 +2190,57 @@
      pro
-cesso
+vide
 rs.add(
+new ProcessorSupplier%3C%3E(() -%3E 
 transact
@@ -2266,16 +2266,17 @@
 reate())
+)
 ;%0A%0A     
@@ -2300,23 +2300,66 @@
 xt) 
-processors.add(
+%7B%0A            providers.add(new ProcessorSupplier%3C%3E(() -%3E 
 trac
@@ -2390,17 +2390,28 @@
 reate())
-;
+);%0A        %7D
 %0A    %7D%0A%0A
@@ -2483,15 +2483,8 @@
 new 
-Default
 Proc
@@ -2484,24 +2484,32 @@
 ew Processor
+Provider
 Chain%3C%3E(proc
@@ -2507,21 +2507,20 @@
 in%3C%3E(pro
-cesso
+vide
 rs);%0A   

Create a new processor for each incoming request