/*
 * 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.example;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.converter.jaxb.JaxbDataFormat;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class DataFormatConcurrentTest extends CamelTestSupport {

    private int size = 2000;
    private int warmupCount = 100;
    private int testCycleCount = 10000;
    private int fooBarSize = 50;

    @Test
    public void testUnmarshalConcurrent() throws Exception {
        template.setDefaultEndpointUri("direct:unmarshal");
        final CountDownLatch latch = new CountDownLatch(warmupCount + testCycleCount);

        context.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:unmarshal")
                        .unmarshal(new JaxbDataFormat("org.apache.camel.example"))
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                latch.countDown();
                            }
                        });
            }
        });

        unmarshal(latch);
    }

    @Test
    public void testUnmarshalFallbackConcurrent() throws Exception {
        template.setDefaultEndpointUri("direct:unmarshalFallback");
        final CountDownLatch latch = new CountDownLatch(warmupCount + testCycleCount);

        context.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:unmarshalFallback")
                        .convertBodyTo(Foo.class)
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                latch.countDown();
                            }
                        });
            }
        });

        unmarshal(latch);
    }

    @Test
    public void testMarshallConcurrent() throws Exception {
        template.setDefaultEndpointUri("direct:marshal");
        final CountDownLatch latch = new CountDownLatch(warmupCount + testCycleCount);

        context.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:marshal")
                        .marshal(new JaxbDataFormat("org.apache.camel.example"))
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                latch.countDown();
                            }
                        });
            }
        });

        marshal(latch);
    }

    @Test
    public void testMarshallFallbackConcurrent() throws Exception {
        template.setDefaultEndpointUri("direct:marshalFallback");
        final CountDownLatch latch = new CountDownLatch(warmupCount + testCycleCount);

        context.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:marshalFallback")
                        .convertBodyTo(String.class)
                        .process(new Processor() {
                            @Override
                            public void process(Exchange exchange) throws Exception {
                                latch.countDown();
                            }
                        });
            }
        });

        marshal(latch);
    }

    @Test
    public void testSendConcurrent() throws Exception {
        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(size);

        // wait for seda consumer to start up properly
        Thread.sleep(1000);

        ExecutorService executor = Executors.newCachedThreadPool();
        for (int i = 0; i < size; i++) {

            // sleep a little so we interleave with the marshaller
            Thread.sleep(1, 500);

            executor.execute(new Runnable() {
                public void run() {
                    PurchaseOrder bean = new PurchaseOrder();
                    bean.setName("Beer");
                    bean.setAmount(23);
                    bean.setPrice(2.5);

                    template.sendBody("seda:start?size=" + size + "&concurrentConsumers=5", bean);
                }
            });
        }

        assertMockEndpointsSatisfied();
    }

    public void unmarshal(final CountDownLatch latch) throws Exception {
        // warm up
        ByteArrayInputStream[] warmUpPayloads = createPayloads(warmupCount);
        for (ByteArrayInputStream payload : warmUpPayloads) {
            template.sendBody(payload);
        }

        final ByteArrayInputStream[] payloads = createPayloads(testCycleCount);
        ExecutorService pool = Executors.newFixedThreadPool(20);
        long start = System.currentTimeMillis();
        for (int i = 0; i < payloads.length; i++) {
            final int finalI = i;
            pool.execute(new Runnable() {
                public void run() {
                    template.sendBody(payloads[finalI]);
                }
            });
        }

        latch.await();
        long end = System.currentTimeMillis();

        log.info("Sending {} messages to {} took {} ms", new Object[] {payloads.length, template.getDefaultEndpoint().getEndpointUri(), end - start});
    }

    public void marshal(final CountDownLatch latch) throws Exception {
        // warm up
        Foo[] warmUpPayloads = createFoo(warmupCount);
        for (Foo payload : warmUpPayloads) {
            template.sendBody(payload);
        }

        final Foo[] payloads = createFoo(testCycleCount);
        ExecutorService pool = Executors.newFixedThreadPool(20);
        long start = System.currentTimeMillis();
        for (int i = 0; i < payloads.length; i++) {
            final int finalI = i;
            pool.execute(new Runnable() {
                public void run() {
                    template.sendBody(payloads[finalI]);
                }
            });
        }

        latch.await();
        long end = System.currentTimeMillis();

        log.info("Sending {} messages to {} took {} ms", new Object[] {payloads.length, template.getDefaultEndpoint().getEndpointUri(), end - start});
    }

    /**
     * the individual size of one record is:
     * fooBarSize = 1  -> 104 bytes
     * fooBarSize = 50 -> 2046 bytes
     * @return the payloads used for this stress test
     * @throws Exception
     */
    public Foo[] createFoo(int testCount) throws Exception {
        Foo[] foos = new Foo[testCount];
        for (int i = 0; i < testCount; i++) {
            Foo foo = new Foo();
            for (int x = 0; x < fooBarSize; x++) {
                Bar bar = new Bar();
                bar.setName("Name: " + x);
                bar.setValue("value: " + x);
                foo.getBarRefs().add(bar);
            }

            foos[i] = foo;
        }

        return foos;
    }

    /**
     * the individual size of one record is:
     * fooBarSize = 1  -> 104 bytes
     * fooBarSize = 50 -> 2046 bytes
     * @return the payloads used for this stress test
     * @throws Exception
     */
    public ByteArrayInputStream[] createPayloads(int testCount) throws Exception {
        Foo foo = new Foo();
        for (int x = 0; x < fooBarSize; x++) {
            Bar bar = new Bar();
            bar.setName("Name: " + x);
            bar.setValue("value: " + x);
            foo.getBarRefs().add(bar);
        }
        Marshaller m = JAXBContext.newInstance(Foo.class, Bar.class).createMarshaller();
        StringWriter writer = new StringWriter();
        m.marshal(foo, writer);

        byte[] payload = writer.toString().getBytes();
        ByteArrayInputStream[] streams = new ByteArrayInputStream[testCount];
        for (int i = 0; i < testCount; i++) {
            streams[i] = new ByteArrayInputStream(payload);
        }

        return streams;
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            public void configure() {
                DataFormat jaxb = new JaxbDataFormat("org.apache.camel.example");

                // use seda that supports concurrent consumers for concurrency
                from("seda:start?size=" + size + "&concurrentConsumers=5")
                        .marshal(jaxb)
                        .convertBodyTo(String.class)
                        .to("mock:result");
            }
        };
    }
}
