/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
apply plugin: 'karaf-featuresgen'

sourceSets {
	test {
		// send javac output and resource copying to the same output directory for test
		// so Pax Exam can more easily find it without explicit TinyBundle hooks
		output.classesDir = "${buildDir}/classes/test"
		output.resourcesDir = output.classesDir
	}
}

configurations {
	karafDistro {
		description = 'Configuration used to isolate the dependency on the Karaf distro'
		transitive = false
	}
	hibernateEntityManager {
		description = 'Used in Karaf feature generation to define the Hibernate JPA dependencies'
		transitive = false
	}
}

ext {
	// MUST use 4.3.1!  4.3.0 was compiled with "-target jsr14".
	// http://blog.osgi.org/2012/10/43-companion-code-for-java-7.html
	osgiCoreVersion = '4.3.1'
	karafVersion = '3.0.3'
	paxExamVersion = '4.4.0'
	paxUrlVersion = '2.4.1'
}

dependencies {
	ext {
		paxExamVersion = '4.4.0'
		paxExamUrlVersion = '2.4.1'
		karafVersion = '3.0.3'
	}

	compile( project( ':hibernate-core' ) )
	compile( project( ':hibernate-entitymanager' ) )

	// MUST use 4.3.1!  4.3.0 was compiled with "-target jsr14".
	// http://blog.osgi.org/2012/10/43-companion-code-for-java-7.html
	compile "org.osgi:org.osgi.core:${osgiCoreVersion}"
	compile "org.osgi:org.osgi.compendium:${osgiCoreVersion}"

	testCompile "org.ops4j.pax.exam:pax-exam:${paxExamVersion}"
	testCompile "org.ops4j.pax.exam:pax-exam-junit4:${paxExamVersion}"
	testCompile "org.ops4j.pax.exam:pax-exam-container-karaf:${paxExamVersion}"
	// Need this explicitly in order to use @Inject -> shouldn't this be a transtive dep of pax-exam?
	//      is there ever a pax exam test that *does not* use this?
	testCompile 'javax.inject:javax.inject:1'

	testCompile( "org.apache.karaf:apache-karaf:${karafVersion}" ) {
		// having trouble finding this one locally
		exclude group: 'org.eclipse', module: 'org.eclipse.osgi'
	}

	karafDistro "org.apache.karaf:apache-karaf:${karafVersion}@tar.gz"
}

mavenPom {
	name = 'Hibernate OSGi Support'
	description = 'Support for running Hibernate O/RM in OSGi environments'
}

def osgiDescription() {
	return mavenPom.description
}

jar {
	manifest {
		instruction 'Bundle-Activator', 'org.hibernate.osgi.HibernateBundleActivator'

		instructionFirst 'Import-Package',
			// TODO: Shouldn't have to explicitly list this, but the plugin
			// generates it with a [1.0,2) version.
			'javax.persistence;version="2.1.0"',
			'javax.persistence.spi;version="2.1.0"'
	}
}


task generateVersionFile {
	File outputFileDir = project.file( "${buildDir}/classes/test/META-INF/hibernate-osgi/" )
	File outputFile = new File( outputFileDir, 'Version.txt' )

	inputs.property( "version", project.version )
	outputs.file outputFile

	doFirst {
		outputFileDir.mkdirs()

		def writer = new FileWriter( outputFile )
		try {
			writer.write( "${project.version}" )
			writer.flush()
		}
		finally {
			writer.close()
		}
	}
}

karafFeatures {
	features {
		hibernateOrm {
			name = 'hibernate-orm'
			description = 'Combines all Hibernate core dependencies and required modules into a single feature'
			projects = [
					rootProject.childProjects.'hibernate-core',
					rootProject.childProjects.'hibernate-entitymanager',
					project
			]
			// According to Christian Schneider, these should not be needed
			bundle {
				match {
					group = 'org.osgi'
					module = 'org.osgi.core'
				}
				include = false
			}
			bundle {
				match {
					group = 'org.osgi'
					module = 'org.osgi.compendium'
				}
				include = false
			}
			bundle {
				match {
					group = 'org.jboss.logging'
					module = 'jboss-logging-annotations'
				}
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-processor'
				include = false
			}
			bundle {
				match {
					group = 'org.hibernate.javax.persistence'
					module = 'hibernate-jpa-2.1-api'
				}
				dependency = true
			}
			bundle {
				match {
					group = 'org.apache.geronimo.specs'
					module = 'geronimo-jta_1.1_spec'
				}
				dependency = true
			}
			bundle {
				match group: 'antlr', module: 'antlr'
				remap group: 'org.apache.servicemix.bundles', module: 'org.apache.servicemix.bundles.antlr', version: '2.7.7_5'
			}
			bundle {
				match group: 'dom4j', module: 'dom4j'
				remap group: 'org.apache.servicemix.bundles', module: 'org.apache.servicemix.bundles.dom4j', version: '1.6.1_5'
			}
		}
		// NOTE : would like to include spatial as well, but we need to wait for
		//		it to not define dependency on postgresql driver
		hibernateEnvers {
			name = 'hibernate-envers'
			description = 'Feature for easily adding Envers support to hibernate-orm'
			dependencyFeatureNames = ['hibernate-orm']
			projects = [rootProject.childProjects.'hibernate-envers']
			bundle {
				match group: 'org.hibernate', module: 'hibernate-core'
				include = false
			}
			bundle {
				match group: 'org.hibernate', module: 'hibernate-osgi'
				include = false
			}
			bundle {
				match group: 'org.hibernate', module: 'hibernate-entitymanager'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-annotations'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-processor'
				include = false
			}
		}
		hibernateInfinispan {
			name = 'hibernate-infinispan'
			description = 'Feature for easily adding Infinispan-based caching support to hibernate-orm'
			dependencyFeatureNames = ['hibernate-orm']
			projects = [rootProject.childProjects.'hibernate-infinispan']
			bundle {
				match group: 'org.hibernate', module: 'hibernate-core'
				include = false
			}
			bundle {
				match group: 'org.hibernate', module: 'hibernate-osgi'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-annotations'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-processor'
				include = false
			}
			bundle {
				match group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.1_spec'
				include = false
			}
			bundle {
				match {
					group = 'org.infinispan'
					module = 'infinispan-commons'
				}
				dependency = true
			}
			bundle {
				match {
					group = 'org.jgroups'
					module = 'jgroups'
				}
				dependency = true
			}
		}
		hibernateEhcache {
			name = 'hibernate-ehcache'
			description = 'Feature for easily adding Ehcache-based caching support to hibernate-orm'
			dependencyFeatureNames = ['hibernate-orm']
			projects = [rootProject.childProjects.'hibernate-ehcache']
			bundle {
				match group: 'org.hibernate', module: 'hibernate-core'
				include = false
			}
			bundle {
				match group: 'org.hibernate', module: 'hibernate-osgi'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-annotations'
				include = false
			}
			bundle {
				match group: 'org.jboss.logging', module: 'jboss-logging-processor'
				include = false
			}
			bundle {
				match {
					group = 'net.sf.ehcache'
					module = 'ehcache'
				}
				dependency = true
			}
		}
	}
}

task generateDependsFile {
	// In order to fully use org.ops4j.pax.exam.CoreOptions.maven() stuff
	// we need to generate a META-INF/maven/dependencies.properties file
	// just like the generate-depends-file Maven goal from ServiceMix/Karaf

	File outputFileDir = project.file( 'target/classes/test/META-INF/maven/' )
	File outputFile = new File( outputFileDir, 'dependencies.properties' )

	outputs.file outputFile

	doFirst {
		outputFileDir.mkdirs()

		Properties properties = new Properties();

		// first we add our GAV info
		properties.setProperty( "groupId", "${project.group}" );
		properties.setProperty( "artifactId", project.name );
		properties.setProperty( "version", "${project.version}" );
		properties.setProperty( "${project.group}/${project.name}/version", "${project.version}" );

		// then for all our deps
		project.configurations.testRuntime.resolvedConfiguration.resolvedArtifacts.each {
			final String keyBase = it.moduleVersion.id.group + '/' + it.moduleVersion.id.name;
			properties.setProperty( "${keyBase}/scope", "compile" )
			properties.setProperty( "${keyBase}/type", it.extension )
			properties.setProperty( "${keyBase}/version", it.moduleVersion.id.version )
		}

		FileOutputStream outputStream = new FileOutputStream( outputFile );
		try {
			properties.store( outputStream, "Generated from Gradle by Hibernate build for PaxExam testing of hibernate-osgi module" )
		}
		finally {
			outputStream.close()
		}
	}
}

task generatePaxExamEnvironmentFile {
	// I found this better/easier than duplicating information...
	description = 'Generates a Properties file that the Pax Exam test can access to know information about the test environment'

	File outputFile = new File( sourceSets.test.output.resourcesDir, 'pax-exam-environment.properties' )
	File karafUnpackDirectory = file( "${buildDir}/karaf-unpack" )

	// set up up-to-date checks
	inputs.files( configurations.testRuntime )
	inputs.property( 'karafUnpackDirectory', karafUnpackDirectory )
	outputs.file( outputFile )

	doFirst {
		// should only be one artifacts..
		File karafDistroFile = configurations.karafDistro.resolvedConfiguration.resolvedArtifacts[0].file

		Properties properties = new Properties();
		properties.setProperty( 'org.ops4j.pax.exam.container.karaf.distroUrl', karafDistroFile.toURI().toURL().toExternalForm() )
		properties.setProperty( 'org.ops4j.pax.exam.container.karaf.unpackDir', karafUnpackDirectory.absolutePath )
		properties.setProperty( 'org.ops4j.pax.exam.container.karaf.version', karafVersion as String )
		properties.setProperty( 'org.ops4j.pax.exam.container.karaf.probe.classesDir', sourceSets.test.output.classesDir.absolutePath )
		properties.setProperty( 'org.ops4j.pax.exam.container.karaf.probe.resourcesDir', sourceSets.test.output.resourcesDir.absolutePath )
		properties.setProperty( 'org.hibernate.osgi.test.karafFeatureFile', karafFeatures.featuresXmlFile.absolutePath )

		outputFile.parentFile.mkdirs()

		FileOutputStream outputStream = new FileOutputStream( outputFile );
		try {
			properties.store( outputStream, "Generated from Gradle by Hibernate build for PaxExam testing of hibernate-osgi module" )
		}
		finally {
			outputStream.close()
		}
	}
}

tasks.test.dependsOn tasks.generateKarafFeatures
tasks.test.dependsOn tasks.jar
tasks.test.dependsOn tasks.generateDependsFile
tasks.test.dependsOn tasks.generatePaxExamEnvironmentFile

// we also need to make sure that hibernate-core, hibernate-entitymanager and hibernate-osgi
// are published to maven-local before running tests
tasks.test.dependsOn rootProject.childProjects.'hibernate-core'.tasks.publishToMavenLocal
tasks.test.dependsOn rootProject.childProjects.'hibernate-entitymanager'.tasks.publishToMavenLocal
tasks.test.dependsOn tasks.publishToMavenLocal

publishing {
	publications {
		mavenJava( MavenPublication ) {
			artifact( project.extensions.karafFeatures.featuresXmlFile ) {
				classifier 'karaf'
				builtBy generateKarafFeatures
			}
		}
	}
}