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

import static javax.persistence.spi.PersistenceUnitTransactionType.JTA;
import static javax.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL;
import static org.junit.Assert.assertEquals;
import static org.osgi.service.jdbc.DataSourceFactory.OSGI_JDBC_DRIVER_CLASS;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import org.apache.aries.jpa.container.itest.entities.Car;
import org.apache.aries.jpa.itest.AbstractCarJPAITest;
import org.apache.aries.jpa.supplier.EmSupplier;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.Coordinator;
import org.osgi.service.jdbc.DataSourceFactory;
import org.osgi.service.jpa.EntityManagerFactoryBuilder;

public abstract class JPAContainerTest extends AbstractCarJPAITest {
    @Inject
    Coordinator coordinator;

    protected abstract String getProviderClassName();
    protected abstract Bundle getProviderBundle();
    
    @Test
    public void testCarEMFBuilder() throws Exception {
        EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
                                                            "(osgi.unit.name=" + DSF_TEST_UNIT + ")");
        
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
        Map<String, Object> props = new HashMap<String, Object>();
        EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
        carLifecycleRL(emf.createEntityManager());
    }

    @Test
    public void testTruckEMFBuilder() throws Exception {
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + DSF_TEST_UNIT + ")");

    	assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
    	
    	Map<String, Object> props = new HashMap<String, Object>();
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	truckLifecycleRL(emf.createEntityManager());
    }

    @Test
    public void testCarEMF() throws Exception {
        carLifecycleRL(getEMF(TEST_UNIT).createEntityManager());
    }

    @Test
    public void testTruckEMF() throws Exception {
    	truckLifecycleRL(getEMF(TEST_UNIT).createEntityManager());
    }
    
    @Test
    public void testCarEMFXA() throws Exception {
        EntityManager em = getEMF(XA_TEST_UNIT).createEntityManager();
        carLifecycleXA(ut, em);
        em.close();
    }

    @Test
    public void testTruckEMFXA() throws Exception {
    	EntityManager em = getEMF(XA_TEST_UNIT).createEntityManager();
    	truckLifecycleXA(ut, em);
    	em.close();
    }

    @Test
    public void testCarDataSourceFactoryLifecycle() throws Exception {
        carLifecycleRL(getEMF(DSF_TEST_UNIT).createEntityManager());
    }

    @Test
    public void testTruckDataSourceFactoryLifecycle() throws Exception {
    	truckLifecycleRL(getEMF(DSF_TEST_UNIT).createEntityManager());
    }

    @Test
    public void testCarDataSourceFactoryXALifecycle() throws Exception {
        EntityManager em = getEMF(DSF_XA_TEST_UNIT).createEntityManager();
        carLifecycleXA(ut, em);
        em.close();
    }

    @Test
    public void testTruckDataSourceFactoryXALifecycle() throws Exception {
    	EntityManager em = getEMF(DSF_XA_TEST_UNIT).createEntityManager();
    	truckLifecycleXA(ut, em);
    	em.close();
    }
    

    @Test
    public void testEmSupplier() throws Exception {
        EmSupplier emSupplier = getService(EmSupplier.class, "(osgi.unit.name=" + XA_TEST_UNIT + ")");
        Coordination coordination = coordinator.begin("test", 0);
        try {
            EntityManager em = emSupplier.get();
            carLifecycleXA(ut, em);

            Query countQuery = em.createQuery("SELECT Count(c) from Car c");
            assertEquals(0l, countQuery.getSingleResult());

            ut.begin();
            em.joinTransaction();
            em.persist(createBlueCar());
            em.persist(createGreenCar());
            ut.commit();

            assertEquals(2l, countQuery.getSingleResult());

            TypedQuery<Car> carQuery = em.createQuery("Select c from Car c ORDER by c.engineSize", Car.class);
            List<Car> list = carQuery.getResultList();
            assertEquals(2, list.size());

            assertBlueCar(list.get(0));
            assertGreenCar(list.get(1));

            ut.begin();
            em.joinTransaction();
            changeToRed(em.find(Car.class, BLUE_PLATE));
            em.remove(em.find(Car.class, GREEN_CAR_PLATE));
            em.persist(createBlackCar());
            ut.commit();

            assertEquals(2l, countQuery.getSingleResult());
            list = carQuery.getResultList();
            assertEquals(2, list.size());

            assertBlackCar(list.get(0));
            assertChangedBlueCar(list.get(1));

            cleanup(em);
        } finally {
            coordination.end();
        }
    }

    private void changeToRed(Car car) {
        car.setNumberOfSeats(2);
        car.setEngineSize(2000);
        car.setColour("red");
    }

    private void cleanup(EntityManager em) throws Exception {
        ut.begin();
        em.joinTransaction();
        delete(em, Car.class, BLACK_CAR_PLATE);
        delete(em, Car.class, BLUE_PLATE);
        ut.commit();
    }

    private void assertChangedBlueCar(Car car) {
        assertEquals(2, car.getNumberOfSeats());
        assertEquals(2000, car.getEngineSize());
        assertEquals("red", car.getColour());
        assertEquals(BLUE_PLATE, car.getNumberPlate());
    }

    @Test
    public void testCarEMFBuilderExternalDS() throws Exception {
    	DataSourceFactory dsf = getService(DataSourceFactory.class, 
    			"(" + OSGI_JDBC_DRIVER_CLASS + "=org.apache.derby.jdbc.EmbeddedDriver)");
       
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
    	
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
    	
    	Properties jdbcProps = new Properties();
    	jdbcProps.setProperty("url", "jdbc:derby:memory:DSFTEST;create=true");
    	
    	Map<String, Object> props = new HashMap<String, Object>();
    	props.put("javax.persistence.nonJtaDataSource", dsf.createDataSource(jdbcProps));
    	props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
    	
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	carLifecycleRL(emf.createEntityManager());
    }

    @Test
    public void testTruckEMFBuilderExternalDS() throws Exception {
    	DataSourceFactory dsf = getService(DataSourceFactory.class, 
    			"(" + OSGI_JDBC_DRIVER_CLASS + "=org.apache.derby.jdbc.EmbeddedDriver)");
    	
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
    	 
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
    	Properties jdbcProps = new Properties();
    	jdbcProps.setProperty("url", "jdbc:derby:memory:DSFTEST;create=true");
    	
    	Map<String, Object> props = new HashMap<String, Object>();
    	props.put("javax.persistence.nonJtaDataSource", dsf.createDataSource(jdbcProps));
    	props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
    	
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	truckLifecycleRL(emf.createEntityManager());
    }

    @Test
    public void testCarEMFBuilderExternalDSXA() throws Exception {
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
    	 
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
    	Map<String, Object> props = new HashMap<String, Object>();
    	props.put("javax.persistence.jtaDataSource", ds);
    	props.put("javax.persistence.transactionType", JTA.name());
    	//EclipseLink also needs a non-jta-datasource
    	props.put("javax.persistence.nonJtaDataSource", ds);
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	carLifecycleXA(ut, emf.createEntityManager());
    }

    @Test
    public void testTruckEMFBuilderExternalDSXA() throws Exception {
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
    	 
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
    	Map<String, Object> props = new HashMap<String, Object>();
    	props.put("javax.persistence.jtaDataSource", ds);
    	props.put("javax.persistence.transactionType", JTA.name());
    	//EclipseLink also needs a non-jta-datasource
    	props.put("javax.persistence.nonJtaDataSource", ds);
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	truckLifecycleXA(ut, emf.createEntityManager());
    }
    
    @Test
    public void testCarEMFBuilderNoNonJTADataSource() throws Exception {
        EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
                        "(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
        
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
        Map<String, Object> props = new HashMap<String, Object>();
        Properties jdbcProps = new Properties();
        jdbcProps.setProperty("url", "jdbc:derby:memory:TESTNOJTA;create=true");
        props.put("javax.persistence.dataSource", dsf.createDataSource(jdbcProps));
        props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
        
        EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
        carLifecycleRL(emf.createEntityManager());
    }
    
    @Test
    public void testTruckEMFBuilderNoNonJTADataSource() throws Exception {
    	EntityManagerFactoryBuilder emfBuilder = getService(EntityManagerFactoryBuilder.class,
    			"(osgi.unit.name=" + EXTERNAL_TEST_UNIT + ")");
    	 
        assertEquals(getProviderClassName(), emfBuilder.getPersistenceProviderName());
    	assertEquals(getProviderBundle(), emfBuilder.getPersistenceProviderBundle());
        
    	Map<String, Object> props = new HashMap<String, Object>();
    	Properties jdbcProps = new Properties();
    	jdbcProps.setProperty("url", "jdbc:derby:memory:TESTNOJTA;create=true");
    	props.put("javax.persistence.dataSource", dsf.createDataSource(jdbcProps));
    	props.put("javax.persistence.transactionType", RESOURCE_LOCAL.name());
    	
    	EntityManagerFactory emf = emfBuilder.createEntityManagerFactory(props);
    	truckLifecycleRL(emf.createEntityManager());
    }

}
