/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.camel.processor;

import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;

import org.apache.camel.Channel;
import org.apache.camel.ContextTestSupport;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.Route;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.EventDrivenConsumerRoute;
import org.apache.camel.util.ServiceHelper;

public class StreamResequencerTest extends ContextTestSupport {

    protected void sendBodyAndHeader(String endpointUri, final Object body, final String headerName, final Object headerValue) {
        template.send(endpointUri, new Processor() {
            public void process(Exchange exchange) {
                Message in = exchange.getIn();
                in.setBody(body);
                in.setHeader(headerName, headerValue);
                in.setHeader("testCase", getName());
            }
        });
    }

    public void testSendMessagesInWrongOrderButReceiveThemInCorrectOrder() throws Exception {
        getMockEndpoint("mock:result").expectedBodiesReceived("msg1", "msg2", "msg3", "msg4");

        sendBodyAndHeader("direct:start", "msg4", "seqnum", 4L);
        sendBodyAndHeader("direct:start", "msg1", "seqnum", 1L);
        sendBodyAndHeader("direct:start", "msg3", "seqnum", 3L);
        sendBodyAndHeader("direct:start", "msg2", "seqnum", 2L);

        assertMockEndpointsSatisfied();
    }

    public void testMultithreaded() throws Exception {
        int numMessages = 100;

        Object[] bodies = new Object[numMessages];
        for (int i = 0; i < numMessages; i++) {
            bodies[i] = "msg" + i;
        }

        getMockEndpoint("mock:result").expectedBodiesReceived(bodies);
        getMockEndpoint("mock:result").setResultWaitTime(20000);

        ProducerTemplate producerTemplate = context.createProducerTemplate();
        ProducerTemplate producerTemplate2 = context.createProducerTemplate();

        ExecutorService service = context.getExecutorServiceManager().newFixedThreadPool(this, getName(), 2);

        service.execute(new Sender(producerTemplate, 0, numMessages, 2));
        service.execute(new Sender(producerTemplate2, 1, numMessages, 2));

        assertMockEndpointsSatisfied();

        ServiceHelper.stopServices(producerTemplate, producerTemplate2);
    }

    @Override
    protected boolean useJmx() {
        boolean enable = "testStreamResequencerTypeWithJmx".equals(getName());
        log.info("Going to {} JMX for the test {}", enable ? "enable" : "disable", getName());

        return enable;
    }

    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                // START SNIPPET: example
                from("direct:start").resequence(header("seqnum")).stream().to("mock:result");
                // END SNIPPET: example
            }
        };
    }

    public void testStreamResequencerTypeWithJmx() throws Exception {
        doTestStreamResequencerType();
    }

    public void testStreamResequencerTypeWithoutJmx() throws Exception {
        doTestStreamResequencerType();
    }

    protected void doTestStreamResequencerType() throws Exception {
        List<Route> list = getRouteList(createRouteBuilder());
        assertEquals("Number of routes created: " + list, 1, list.size());

        Route route = list.get(0);
        EventDrivenConsumerRoute consumerRoute = assertIsInstanceOf(EventDrivenConsumerRoute.class, route);

        Channel channel = unwrapChannel(consumerRoute.getProcessor());

        assertIsInstanceOf(DefaultErrorHandler.class, channel.getErrorHandler());
        assertIsInstanceOf(StreamResequencer.class, channel.getNextProcessor());
    }

    private static class Sender implements Runnable {

        private final ProducerTemplate template;
        private final int start;
        private final int end;
        private final int increment;
        private final Random random;

        public Sender(ProducerTemplate template, int start, int end, int increment) {
            this.template = template;
            this.start = start;
            this.end = end;
            this.increment = increment;
            random = new Random();
        }

        @Override
        public void run() {
            for (long i = start; i < end; i += increment) {
                try {
                    // let's sleep randomly
                    Thread.sleep(random.nextInt(20));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }

                template.sendBodyAndHeader("direct:start", "msg" + i, "seqnum", i);
            }
        }

    }
}
