/*
 * 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.sling.event.it;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.sling.event.impl.Barrier;
import org.apache.sling.event.impl.jobs.config.ConfigurationConstants;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.NotificationConstants;
import org.apache.sling.event.jobs.Queue;
import org.apache.sling.event.jobs.QueueConfiguration;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerMethod;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.factoryConfiguration;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerMethod.class)
public class OrderedQueueTest extends AbstractJobHandlingTest {

    @Configuration
    public Option[] configuration() {
        return options(
            baseConfiguration(),
            // create ordered test queue
            factoryConfiguration("org.apache.sling.event.jobs.QueueConfiguration")
                .put(ConfigurationConstants.PROP_NAME, "orderedtest")
                .put(ConfigurationConstants.PROP_TYPE, QueueConfiguration.Type.ORDERED.name())
                .put(ConfigurationConstants.PROP_TOPICS, "sling/orderedtest/*")
                .put(ConfigurationConstants.PROP_RETRIES, 2)
                .put(ConfigurationConstants.PROP_RETRY_DELAY, 2000L)
                .asOption()
        );
    }

    /**
     * Ordered Queue Test
     */
    @Test(timeout = DEFAULT_TEST_TIMEOUT)
    public void testOrderedQueue() throws Exception {

        // register consumer and event handler
        final Barrier cb = new Barrier(2);
        final AtomicInteger count = new AtomicInteger(0);
        final AtomicInteger parallelCount = new AtomicInteger(0);
        this.registerJobConsumer("sling/orderedtest/*",
                new JobConsumer() {

                    private volatile int lastCounter = -1;

                    @Override
                    public JobResult process(final Job job) {
                        final int counter = job.getProperty("counter", -10);
                        assertNotEquals("Counter property is missing", -10, counter);
                        assertTrue("Counter should only increment by max of 1 " + counter + " - " + lastCounter,
                                counter == lastCounter || counter == lastCounter +1);
                        lastCounter = counter;
                        if ("sling/orderedtest/start".equals(job.getTopic()) ) {
                            cb.block();
                            return JobResult.OK;
                        }
                        if ( parallelCount.incrementAndGet() > 1 ) {
                            parallelCount.decrementAndGet();
                            return JobResult.FAILED;
                        }
                        final String topic = job.getTopic();
                        if ( topic.endsWith("sub1") ) {
                            final int i = (Integer)job.getProperty(Job.PROPERTY_JOB_RETRY_COUNT);
                            if ( i == 0 ) {
                                parallelCount.decrementAndGet();
                                return JobResult.FAILED;
                            }
                        }
                        try {
                            Thread.sleep(30);
                        } catch (InterruptedException ie) {
                            // ignore
                        }
                        parallelCount.decrementAndGet();
                        return JobResult.OK;
                    }
                });
        this.registerEventHandler(NotificationConstants.TOPIC_JOB_FINISHED,
                new EventHandler() {

                    @Override
                    public void handleEvent(final Event event) {
                        count.incrementAndGet();
                    }
                });

        // we first sent one event to get the queue started
        final Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("counter", -1);
        jobManager.addJob("sling/orderedtest/start", properties);
        assertTrue("No event received in the given time.", cb.block(5));
        cb.reset();

        // get the queue
        final Queue q = jobManager.getQueue("orderedtest");
        assertNotNull("Queue 'orderedtest' should exist!", q);

        // suspend it
        q.suspend();

        final int NUM_JOBS = 30;

        // we start "some" jobs:
        for(int i = 0; i < NUM_JOBS; i++ ) {
            final String subTopic = "sling/orderedtest/sub" + (i % 10);
            properties.clear();
            properties.put("counter", i);
            jobManager.addJob(subTopic, properties);
        }
        // start the queue
        q.resume();
        while ( count.get() < NUM_JOBS +1 ) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException ie) {
                // ignore
            }
        }
        // we started one event before the test, so add one
        assertEquals("Finished count", NUM_JOBS + 1, count.get());
        assertEquals("Finished count", NUM_JOBS + 1, jobManager.getStatistics().getNumberOfFinishedJobs());
        assertEquals("Finished count", NUM_JOBS + 1, q.getStatistics().getNumberOfFinishedJobs());
        assertEquals("Failed count", NUM_JOBS / 10, q.getStatistics().getNumberOfFailedJobs());
        assertEquals("Cancelled count", 0, q.getStatistics().getNumberOfCancelledJobs());
    }
}