plugins {
	id 'java-library'
	id 'maven-publish'
	id 'signing'
	id 'jacoco'
	id 'com.diffplug.spotless' version '5.17.0'
}

allprojects {

	repositories {
		mavenCentral()
	}
}

project.group = "com.microsoft.onnxruntime"
project.version = rootProject.file('../version.txt').text.trim()

// cmake runs will inform us of the build directory of the current run
def cmakeBuildDir = System.properties['cmakeBuildDir']
def cmakeJavaDir = "${cmakeBuildDir}/java"
def cmakeNativeLibDir = "${cmakeJavaDir}/native-lib"
def cmakeNativeJniDir = "${cmakeJavaDir}/native-jni"
def cmakeNativeTestDir = "${cmakeJavaDir}/native-test"
def cmakeBuildOutputDir = "${cmakeJavaDir}/build"

def mavenUser = System.properties['mavenUser']
def mavenPwd = System.properties['mavenPwd']

def mavenArtifactId = project.name

java {
	sourceCompatibility = JavaVersion.VERSION_1_8
	targetCompatibility = JavaVersion.VERSION_1_8
}

// This jar tasks serves as a CMAKE signalling
// mechanism. The jar will be overwritten by allJar task
jar {
}

// Add explicit sources jar with pom file.
task sourcesJar(type: Jar, dependsOn: classes) {
	classifier = "sources"
	from sourceSets.main.allSource
	into("META-INF/maven/$project.group/$mavenArtifactId") {
		from { generatePomFileForMavenPublication }
		rename ".*", "pom.xml"
	}
}

// Add explicit javadoc jar with pom file
task javadocJar(type: Jar, dependsOn: javadoc) {
	classifier = "javadoc"
	from javadoc.destinationDir
	into("META-INF/maven/$project.group/$mavenArtifactId") {
		from { generatePomFileForMavenPublication }
		rename ".*", "pom.xml"
	}
}

wrapper {
	gradleVersion = '7.5.1'
}

spotless {
	java {
		removeUnusedImports()
		googleJavaFormat()
	}
	format 'gradle', {
		target '**/*.gradle'
		trimTrailingWhitespace()
		indentWithTabs()
	}
}

compileJava {
	dependsOn spotlessJava
	options.compilerArgs += ["-h", "${project.buildDir}/headers/"]
	if (!JavaVersion.current().isJava8()) {
		// Ensures only methods present in Java 8 are used
		options.compilerArgs.addAll(['--release', '8'])
		// Gradle versions before 6.6 require that these flags are unset when using "-release"
		java.sourceCompatibility = null
		java.targetCompatibility = null
	}
}

compileTestJava {
	if (!JavaVersion.current().isJava8()) {
		// Ensures only methods present in Java 8 are used
		options.compilerArgs.addAll(['--release', '8'])
		// Gradle versions before 6.6 require that these flags are unset when using "-release"
		java.sourceCompatibility = null
		java.targetCompatibility = null
	}
}

sourceSets.test {
	// add test resource files
	resources.srcDirs += [
		"${rootProject.projectDir}/../java/testdata"
	]
	if (cmakeBuildDir != null) {
		// add compiled native libs
		resources.srcDirs += [
			cmakeNativeLibDir,
			cmakeNativeJniDir,
			cmakeNativeTestDir
		]
	}
}

if (cmakeBuildDir != null) {
	// generate tasks to be called from cmake

	// Overwrite jar location
	task allJar(type: Jar) {
		manifest {
			attributes('Automatic-Module-Name': project.group,
					'Implementation-Title': 'onnxruntime-extensions',
					'Implementation-Version': project.version)
		}
		into("META-INF/maven/$project.group/$mavenArtifactId") {
			from { generatePomFileForMavenPublication }
			rename ".*", "pom.xml"
		}
		from sourceSets.main.output
		from cmakeNativeJniDir
		from cmakeNativeLibDir
	}

	task cmakeBuild(type: Copy) {
		from project.buildDir
		include 'libs/**'
		include 'docs/**'
		into cmakeBuildOutputDir
	}
	cmakeBuild.dependsOn allJar
	cmakeBuild.dependsOn sourcesJar
	cmakeBuild.dependsOn javadocJar
	cmakeBuild.dependsOn javadoc

	task cmakeCheck(type: Copy) {
		from project.buildDir
		include 'reports/**'
		into cmakeBuildOutputDir
	}
	cmakeCheck.dependsOn check
}

dependencies {
	testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
	testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
	testImplementation 'com.google.protobuf:protobuf-java:3.20.1'
}

processTestResources {
	duplicatesStrategy(DuplicatesStrategy.INCLUDE) // allows duplicates in the test resources
}

test {
	java {
		dependsOn spotlessJava
	}
	if (System.getProperty("JAVA_FULL_TEST") != null) {
		// Forces each test class to be run in a separate JVM,
		// which is necessary for testing the environment thread pool which is ignored if full test is not set.
		forkEvery 1
	}
	useJUnitPlatform()
	if (cmakeBuildDir != null) {
		workingDir cmakeBuildDir
	}
	systemProperties System.getProperties().subMap(['JAVA_FULL_TEST'])
	testLogging {
		events "passed", "skipped", "failed"
		showStandardStreams = true
		showStackTraces = true
		exceptionFormat = "full"
	}
}

jacocoTestReport {
	reports {
		xml.enabled true
		csv.enabled true
		html.destination file("${buildDir}/jacocoHtml")
	}
}

publishing {
	publications {
		maven(MavenPublication) {
			groupId = project.group
			artifactId = mavenArtifactId
			version = project.version

			from components.java
			pom {
				name = 'onnxruntime-extensions'
				description = 'ONNXRuntime-Extensions is a library for pre- and post-processing.'
				url = 'https://microsoft.github.io/onnxruntime/'
				licenses {
					license {
						name = 'MIT License'
						url = 'https://opensource.org/licenses/MIT'
					}
				}
				organization {
					name = 'Microsoft'
					url = 'http://www.microsoft.com'
				}
				scm {
					connection = 'scm:git:git://github.com:microsoft/onnxruntime-extensions.git'
					developerConnection = 'scm:git:ssh://github.com/microsoft/onnxruntime-extensions.git'
					url = 'http://github.com/microsoft/onnxruntime-extensions'
				}
				developers {
					developer {
						id = 'onnxruntime'
						name = 'ONNX Runtime'
						email = 'onnxruntime@microsoft.com'
					}
				}
			}
		}
	}
	repositories {
		maven {
			url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
			credentials {
				username mavenUser
				password mavenPwd
			}
		}
	}
}

// Generates a task signMavenPublication that will
// build all artifacts.
signing {
	// Queries env vars:
	// ORG_GRADLE_PROJECT_signingKey
	// ORG_GRADLE_PROJECT_signingPassword but can be changed to properties
	def signingKey = findProperty("signingKey")
	def signingPassword = findProperty("signingPassword")
	useInMemoryPgpKeys(signingKey, signingPassword)
	sign publishing.publications.maven
}
