/* ====================================================================
   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.
==================================================================== */

import java.util.regex.Pattern

plugins {
    id 'java'
    id 'maven-publish'
    id 'java-library'
}

final String JAVA9_SRC = 'src/main/java9'
final String JAVA9_OUT = "${buildDir}/classes/java9/main/"
final String TEST9_SRC = 'src/test/java9'
final String TEST9_OUT = "${buildDir}/classes/java9/test/"
final String VERSIONS9 = 'META-INF/versions/9'

configurations {
    tests
    javadocs
}

sourceSets {
    main {
        if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
            output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
        }
    }
    test {
        if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
            output.dir(TEST9_OUT, builtBy: 'cacheTest9')
        }
    }
}

dependencies {
    api "commons-codec:commons-codec:${commonsCodecVersion}"
    api 'org.apache.commons:commons-collections4:4.4'
    api "org.apache.commons:commons-math3:${commonsMathVersion}"
    api 'com.zaxxer:SparseBitSet:1.2'
    implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
    implementation 'javax.activation:activation:1.1.1'

    testImplementation 'org.reflections:reflections:0.9.12'
    testImplementation 'org.apache.ant:ant:1.10.9'

    testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"

    javadocs project(':poi-ooxml')
    javadocs project(':poi-scratchpad')
}

final String MODULE_NAME = 'org.apache.poi.poi'
final Pattern MODULE_NOT_REGEX = ~'(poi[/\\\\][^/\\\\]+$|batik-script)'
final Pattern MODULE_REGEX = ~'\\.jar$'
final List MODULE_PATH = sourceSets.test.runtimeClasspath.findAll{ it.path =~ MODULE_REGEX && !(it.path =~ MODULE_NOT_REGEX) }.collect{ it.parent }.unique()

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
    withJavadocJar()
    withSourcesJar()
}


task compileJava9(type: JavaCompile) {
    dependsOn 'compileJava'

    sourceCompatibility = 9
    targetCompatibility = 9
    destinationDirectory = file(JAVA9_OUT + VERSIONS9)
    source = file(JAVA9_SRC)
    classpath = files()
    options.compilerArgs = [
        '--patch-module', "${MODULE_NAME}=${sourceSets.main.output.classesDirs.asPath}",
        '--module-path', sourceSets.main.compileClasspath.asPath
    ]
}

task cacheJava9(type: Copy) {
    dependsOn 'compileJava9'

    from(file(JAVA9_OUT + VERSIONS9))
    into(JAVA9_SRC)
}

task compileTest9(type: JavaCompile) {
    dependsOn 'compileTestJava'

    sourceCompatibility = 9
    targetCompatibility = 9
    destinationDirectory = file(TEST9_OUT + VERSIONS9)
    source = file(TEST9_SRC)
    options.compilerArgs = [
        '--patch-module', "${MODULE_NAME}=${(sourceSets.main.output.classesDirs + sourceSets.test.output.classesDirs).asPath}",
        '--module-path', files(MODULE_PATH).asPath
    ]
    classpath = files()
}


task cacheTest9(type: Copy) {
    dependsOn 'compileTest9'

    from(file(TEST9_OUT + VERSIONS9))
    into(TEST9_SRC)
}


jar {
    destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")

    if (JavaVersion.current() == JavaVersion.VERSION_1_8) {
        into('META-INF/versions/9') {
            from JAVA9_SRC include '*.class'
        }
    }

    manifest {
        attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
    }
}

// Create a separate jar for test-code to depend on it in other projects
// See http://stackoverflow.com/questions/5144325/gradle-test-dependency
task testJar(type: Jar, dependsOn: testClasses) {
    destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-tests")

    classifier 'tests'
    // ignore second module-info.class from main
    duplicatesStrategy = 'exclude'

    if (JavaVersion.current() == JavaVersion.VERSION_1_8) {
        into('META-INF/versions/9') {
            from TEST9_SRC include '*.class'
        }
    }

    from sourceSets.test.output + sourceSets.main.output

    manifest {
        attributes('Automatic-Module-Name': MODULE_NAME, 'Multi-Release': 'true')
    }
}

sourcesJar {
    destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")
    exclude 'META-INF/services/**'
}

test {
    dependsOn 'testJar'

    useJUnitPlatform()

    doFirst {
        jvmArgs = [
            '-Djava.io.tmpdir=build',
            '-DPOI.testdata.path=../test-data',
            '-Djava.awt.headless=true',
            '-Djava.locale.providers=JRE,CLDR',
            '-Duser.language=en',
            '-Duser.country=US',
            '-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl',
            "-Dversion.id=${project.version}",
            '-ea',
            '-Djunit.jupiter.execution.parallel.enabled=true',
            '-Djunit.jupiter.execution.parallel.config.strategy=fixed',
            '-Djunit.jupiter.execution.parallel.config.fixed.parallelism=3'
            // -Xjit:verbose={compileStart|compileEnd},vlog=build/jit.log${no.jit.sherlock}   ... if ${isIBMVM}
        ]
        if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
            jvmArgs += [
                '-Dsun.reflect.debugModuleAccessChecks=true',
                '-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
                '--illegal-access=warn',

                '--add-modules', MODULE_NAME,
                // see https://github.com/java9-modularity/gradle-modules-plugin/issues/97
                // opposed to the recommendation there, it doesn't work to add ... to the dependencies
                // testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.7.1'
                // gradles gradle-worker.jar is still not a JPMS module and thus runs as unnamed module
                '--add-exports','org.junit.platform.commons/org.junit.platform.commons.util=ALL-UNNAMED',
                '--add-exports','org.junit.platform.commons/org.junit.platform.commons.logging=ALL-UNNAMED',

                '--module-path', '../build/dist/maven/poi-tests:' + files(MODULE_PATH).asPath,
            ]
        }
    }
}

javadoc {
    failOnError = true
    doFirst {
        options {
            if (JavaVersion.current().isJava9Compatible()) {
                addBooleanOption('html5', true)
            }
            links 'https://poi.apache.org/apidocs/dev/'
            links 'https://docs.oracle.com/javase/8/docs/api/'
            use = true
            splitIndex = true
            source = "1.8"
            classpath += configurations.javadocs.files
        }
    }
}

artifacts {
    tests testJar
}

publishing {
    publications {
        POI(MavenPublication) {
            artifactId project.archivesBaseName

            from components.java

            pom {
                name = 'Apache POI'
                description = 'Apache POI - Java API To Access Microsoft Format Files'
            }
        }
    }
}

generatePomFileForPOIPublication.destination = "../build/dist/maven/${project.archivesBaseName}/${project.archivesBaseName}-${project.version}.pom"
