/*  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.aries.jpa.blueprint.aries.itest;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import org.apache.aries.jpa.container.itest.entities.Car;
import org.apache.aries.jpa.container.itest.entities.CarService;
import org.apache.aries.jpa.itest.AbstractCarJPAITest;
import org.junit.Assert;
import org.junit.Test;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.Coordinator;

public class BlueprintTest extends AbstractCarJPAITest {
    @Inject
    Coordinator coordinator;
    
    @Inject
    UserTransaction ut;
    
    @Test
    public void testCoordination() {
        assertNoCoordination();
        CarService carService = getCarService("em");
        assertNoCars(carService);
        for (int c=0; c<100; c++) {
            System.out.println(c);
            Coordination coordination = coordinator.begin("testCoordination", 0);
            try {
                carService.addCar(createBlueCar());
                Collection<Car> cars = carService.getCars();
                carService.updateCar(cars.iterator().next());
            } finally {
                coordination.end();
            }
            carService.deleteCar(BLUE_CAR_PLATE);
            Assert.assertEquals(0, carService.getCars().size());
        }
    }
    
    @Test
    public void testInjectToMethod() throws Exception {
        carLifecycle(getCarService("method"));
    }

    @Test
    public void testMultiAnnotation() throws Exception {
        carLifecycle(getCarService("multiannotation"));
    }

    @Test
    public void testEmf() throws Exception {
        carLifecycle(getCarService("emf"));
    }

    @Test
    public void testEm() throws Exception {
        carLifecycle(getCarService("em"));
    }
    
    @Test
    public void testEmJtaAnn() throws Exception {
        carLifecycle(getCarService("emJtaAnn"));
    }

    @Test
    public void testSupplier() throws Exception {
        carLifecycle(getCarService("supplier"));
    }
    
    @Test
    public void testRealTransactional() throws Exception {
        carRealTransactionalLifecycle(getCarService("emJtaAnn"));
    }
    
    @Test
    public void testCoordinationLifecycle() throws InterruptedException, ExecutionException {
        CarService carService = getCarService("em");
        assertNoCars(carService);
        Runnable carLifeCycle = getService(Runnable.class, "(type=carCoordinated)");
        carLifeCycle.run();
        ExecutorService exec = Executors.newFixedThreadPool(20);
        List<Future<?>> futures = new ArrayList<Future<?>>();
        for (int c=0; c<100; c++) {
            futures.add(exec.submit(carLifeCycle));
        }
        exec.shutdown();
        exec.awaitTermination(30, TimeUnit.SECONDS);
        for (Future<?> future : futures) {
            future.get();
        }
        assertNoCars(carService);
    }

    private CarService getCarService(String type) {
        return getService(CarService.class, "(type=" + type + ")");
    }

    private void carLifecycle(CarService carService) {
        assertNoCoordination();
        if (carService.getCar(BLACK_CAR_PLATE) != null) {
            carService.deleteCar(BLUE_CAR_PLATE);
        }
        carService.addCar(createBlueCar());
        assertBlueCar(carService.getCar(BLUE_CAR_PLATE));
        carService.deleteCar(BLUE_CAR_PLATE);
    }
    
    private void carRealTransactionalLifecycle(CarService carService) throws IllegalStateException, SystemException, NotSupportedException {
        assertNoCoordination();
        if (carService.getCar(BLACK_CAR_PLATE) != null) {
            carService.deleteCar(BLUE_CAR_PLATE);
        }
        ut.begin();
        carService.addCar(createBlueCar());
        ut.rollback();
        Assert.assertNull(carService.getCar(BLUE_CAR_PLATE));
    }

    private void assertNoCoordination() {
        Coordination coord = coordinator.peek();
        Assert.assertNull("There should not be a coordination on this thread", coord);
    }
    
    private void assertNoCars(CarService carService) {
        Assert.assertEquals("Invalid number of cars", 0, carService.getCars().size());
    }

    @Configuration
    public Option[] configuration() {
        return new Option[] {
            baseOptions(), //
            jta12Bundles(), //
            ariesJpa20(), //
            hibernate(), //
            derbyDSF(), //
            testBundle(), //
            testBundleBlueprint(),
        // debug()
        };
    }
}
