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) {
    archiveClassifier = "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) {
    archiveClassifier = "javadoc"
    from javadoc.destinationDir
    into("META-INF/maven/$project.group/$mavenArtifactId") {
        from { generatePomFileForMavenPublication }
        rename ".*", "pom.xml"
    }
}

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.required = true
        csv.required = 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
}
