/*
 * 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 WARRANTIESOR 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.tx.control.itests;

import static java.lang.Boolean.getBoolean;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.CoreOptions.when;

import java.io.File;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;

import javax.persistence.EntityManager;

import org.apache.aries.itest.AbstractIntegrationTest;
import org.h2.tools.Server;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.CoreOptions;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.ProbeBuilder;
import org.ops4j.pax.exam.TestProbeBuilder;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.jdbc.DataSourceFactory;
import org.osgi.service.jpa.EntityManagerFactoryBuilder;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public abstract class AbstractJPATransactionTest extends AbstractIntegrationTest {

	protected static final String TX_CONTROL_FILTER = "tx.control.filter";
	protected static final String ARIES_EMF_BUILDER_TARGET_FILTER = "aries.emf.builder.target.filter";
	protected static final String IS_XA = "aries.test.is.xa";

	protected TransactionControl txControl;

	protected EntityManager em;

	private Server server;

	@Before
	public void setUp() throws Exception {
		
		txControl = context().getService(TransactionControl.class, System.getProperty(TX_CONTROL_FILTER), 5000);
		
		server = Server.createTcpServer("-tcpPort", "0");
		server.start();
		
		String jdbcUrl = "jdbc:h2:tcp://127.0.0.1:" + server.getPort() + "/" + getRemoteDBPath();
		
		em = configuredEntityManager(jdbcUrl);
	}

	private String getRemoteDBPath() {
		String fullResourceName = getClass().getName().replace('.', '/') + ".class";
		
		String resourcePath = getClass().getClassLoader().getResource(fullResourceName).getPath();
		
		File testClassesDir = new File(resourcePath.substring(0, resourcePath.length() - fullResourceName.length()));
		
		return new File(testClassesDir.getParentFile(), "testdb/db1").getAbsolutePath();
	}

	private EntityManager configuredEntityManager(String jdbcUrl) throws IOException {
		
		Dictionary<String, Object> props = getBaseProperties();
		
		props.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, "org.h2.Driver");
		props.put(DataSourceFactory.JDBC_URL, jdbcUrl);
		props.put(EntityManagerFactoryBuilder.JPA_UNIT_NAME, "test-unit");
		
		String filter = System.getProperty(ARIES_EMF_BUILDER_TARGET_FILTER);
		
		if(filter != null) {
			props.put(ARIES_EMF_BUILDER_TARGET_FILTER, filter);
		}
		
		ConfigurationAdmin cm = context().getService(ConfigurationAdmin.class, 5000);
		
		String pid = getBoolean(IS_XA) ? "org.apache.aries.tx.control.jpa.xa" :
				"org.apache.aries.tx.control.jpa.local"; 
		
		System.out.println("Configuring connection provider with pid " + pid);
		
		org.osgi.service.cm.Configuration config = cm.createFactoryConfiguration(
				pid, null);
		config.update(props);
		
		return context().getService(JPAEntityManagerProvider.class, 5000).getResource(txControl);
	}

	protected Dictionary<String, Object> getBaseProperties() {
		return new Hashtable<>();
	}
	
	@After
	public void tearDown() {

		clearConfiguration();
		
		if(server != null) {
			server.stop();
		}

		em = null;
	}

	private void clearConfiguration() {
		ConfigurationAdmin cm = context().getService(ConfigurationAdmin.class, 5000);
		org.osgi.service.cm.Configuration[] cfgs = null;
		try {
			cfgs = cm.listConfigurations(null);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		if(cfgs != null) {
			for(org.osgi.service.cm.Configuration cfg : cfgs) {
				try {
					cfg.delete();
				} catch (Exception e) {}
			}
			try {
				Thread.sleep(250);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@ProbeBuilder
	public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
	    // makes sure the generated Test-Bundle contains this import!
	    probe.setHeader("Meta-Persistence", "META-INF/persistence.xml");
	    return probe;
	}
	
	@Configuration
	public Option[] localTxConfiguration() {
		String localRepo = System.getProperty("maven.repo.local");
		if (localRepo == null) {
			localRepo = System.getProperty("org.ops4j.pax.url.mvn.localRepository");
		}
		
		return options(junitBundles(), systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
				when(localRepo != null)
				.useOptions(CoreOptions.vmOption("-Dorg.ops4j.pax.url.mvn.localRepository=" + localRepo)),
				mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit").versionAsInProject(),
				localTxControlService(),
				localJpaResourceProviderWithH2(),
				jpaProvider(),
				ariesJPA(),
				mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject(),
				mavenBundle("org.ops4j.pax.logging", "pax-logging-api").versionAsInProject(),
				mavenBundle("org.ops4j.pax.logging", "pax-logging-service").versionAsInProject()
				
//				,CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
				);
	}

	@Configuration
	public Option[] xaTxConfiguration() {
		String localRepo = System.getProperty("maven.repo.local");
		if (localRepo == null) {
			localRepo = System.getProperty("org.ops4j.pax.url.mvn.localRepository");
		}
		
		return options(junitBundles(), systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
				when(localRepo != null)
				.useOptions(CoreOptions.vmOption("-Dorg.ops4j.pax.url.mvn.localRepository=" + localRepo)),
				mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit").versionAsInProject(),
				systemProperty(IS_XA).value(Boolean.TRUE.toString()),
				xaTxControlService(),
				xaJpaResourceProviderWithH2(),
				jpaProvider(),
				ariesJPA(),
				mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject(),
				mavenBundle("org.ops4j.pax.logging", "pax-logging-api").versionAsInProject(),
				mavenBundle("org.ops4j.pax.logging", "pax-logging-service").versionAsInProject()
				
//				,CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005")
				);
	}

	public Option localTxControlService() {
		return CoreOptions.composite(
				systemProperty(TX_CONTROL_FILTER).value("(osgi.local.enabled=true)"),
				mavenBundle("org.apache.aries.tx-control", "tx-control-service-local").versionAsInProject());
	}

	public Option xaTxControlService() {
		return CoreOptions.composite(
				systemProperty(TX_CONTROL_FILTER).value("(osgi.xa.enabled=true)"),
				mavenBundle("org.apache.aries.tx-control", "tx-control-service-xa").versionAsInProject());
	}

	public Option localJpaResourceProviderWithH2() {
		return CoreOptions.composite(
				mavenBundle("com.h2database", "h2").versionAsInProject(),
				mavenBundle("org.apache.aries.tx-control", "tx-control-provider-jpa-local").versionAsInProject());
	}
	
	public Option xaJpaResourceProviderWithH2() {
		return CoreOptions.composite(
				mavenBundle("com.h2database", "h2").versionAsInProject(),
				mavenBundle("org.apache.aries.tx-control", "tx-control-provider-jpa-xa").versionAsInProject());
	}
	
	public Option ariesJPA() {
		return mavenBundle("org.apache.aries.jpa", "org.apache.aries.jpa.container", ariesJPAVersion());
	}

	protected String ariesJPAVersion() {
		return "2.3.0";
	}
	
	protected abstract Option jpaProvider();
}
