import java.util.regex.Pattern

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

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 project(':poi')
    api project(path:':poi', configuration: 'archives')
    implementation "commons-codec:commons-codec:${commonsCodecVersion}"
    implementation "org.apache.commons:commons-math3:${commonsMathVersion}"
    implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"

    testImplementation project(path: ':poi', configuration: 'tests')
    testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"

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

final MODULE_NAME = 'org.apache.poi.scratchpad'
final Pattern MODULE_NOT_REGEX = ~'(poi[/\\\\][^/\\\\]+$|batik-script)'
final Pattern MODULE_REGEX = ~'\\.jar$'
final List MAIN_MODULE_PATH = sourceSets.main.runtimeClasspath.findAll{ it.path =~ MODULE_REGEX }.collect{ it.parent }.unique()
final List TEST_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', ':poi:jar'

    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', files(MAIN_MODULE_PATH).asPath
    ]
}

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

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

task compileTest9(type: JavaCompile) {
    dependsOn 'compileTestJava', ':poi:jar'

    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(TEST_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/**'
}

artifacts {
    tests testJar
}

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-scratchpad-tests:' + files(TEST_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
        }
    }
}

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

            from components.java

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

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