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

configurations {
    runtimeClasspath {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }

    compileClasspath {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }

    broken
    tests
    javadocs
}

sourceSets {
    main {
        if (jdkVersion > 8) {
            output.dir(JAVA9_OUT, builtBy: 'cacheJava9')
        }
    }
    test {
        if (jdkVersion > 8) {
            output.dir(TEST9_OUT, builtBy: 'cacheTest9')
        }
    }
}

java {
    registerFeature('signing') {
        usingSourceSet(sourceSets.main)
    }
    registerFeature('render') {
        usingSourceSet(sourceSets.main)
    }
    registerFeature('rendersign') {
        usingSourceSet(sourceSets.main)
    }
}

dependencies {
    api project(':poi')
    api project(':poi-ooxml-full')
    api project(path: ':poi-ooxml-full', configuration: 'archives')

    api "org.apache.xmlbeans:xmlbeans:${xmlbeansVersion}"
    api "org.apache.commons:commons-compress:${commonsCompressVersion}"
    api "commons-io:commons-io:${commonsIoVersion}"
    api 'com.github.virtuald:curvesapi:1.07'
    api "org.apache.logging.log4j:log4j-api:${log4jVersion}"
    api 'org.apache.commons:commons-collections4:4.4'

    signingImplementation 'org.apache.santuario:xmlsec:3.0.0'
    signingImplementation "org.bouncycastle:bcpkix-jdk15on:${bouncyCastleVersion}"
    signingImplementation "org.bouncycastle:bcutil-jdk15on:${bouncyCastleVersion}"

    rendersignImplementation 'org.apache.santuario:xmlsec:3.0.0'
    rendersignImplementation "org.bouncycastle:bcpkix-jdk15on:${bouncyCastleVersion}"
    rendersignImplementation "org.bouncycastle:bcutil-jdk15on:${bouncyCastleVersion}"

    renderImplementation "org.apache.pdfbox:pdfbox:${pdfboxVersion}"
    renderImplementation "de.rototor.pdfbox:graphics2d:${graphics2dVersion}"
    renderImplementation "org.apache.xmlgraphics:batik-svggen:${batikVersion}"
    renderImplementation("org.apache.xmlgraphics:batik-svgrasterizer:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }
    renderImplementation("org.apache.xmlgraphics:batik-codec:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }
    renderImplementation("org.apache.xmlgraphics:batik-bridge:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }

    rendersignImplementation "org.apache.pdfbox:pdfbox:${pdfboxVersion}"
    rendersignImplementation "de.rototor.pdfbox:graphics2d:${graphics2dVersion}"
    rendersignImplementation "org.apache.xmlgraphics:batik-svggen:${batikVersion}"
    rendersignImplementation("org.apache.xmlgraphics:batik-svgrasterizer:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }
    rendersignImplementation("org.apache.xmlgraphics:batik-codec:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }
    rendersignImplementation("org.apache.xmlgraphics:batik-bridge:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }


    if (!NO_SCRATCHPAD) {
         testImplementation project(':poi-scratchpad')
         testImplementation project(path:':poi-scratchpad', configuration:'tests')
    }
    testImplementation project(path:':poi', configuration:'tests')
    testImplementation project(path:':poi-ooxml-lite-agent', configuration: 'archives')
    testRuntimeOnly "org.apiguardian:apiguardian-api:${apiGuardianVersion}"
    testImplementation 'org.xmlunit:xmlunit-core:2.9.0'
    testImplementation 'org.reflections:reflections:0.10.2'
    testImplementation 'org.openjdk.jmh:jmh-core:1.35'
    testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.35'
    testImplementation 'com.google.guava:guava:31.1-jre'
    testImplementation 'org.tukaani:xz:1.9'
    testImplementation 'com.github.rzymek:opczip:1.2.0'

    // prevent slf4j warnings coming from xmlsec -> slf4j-api 1.7.x dependency
    // see https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/
    testImplementation "org.apache.logging.log4j:log4j-slf4j18-impl:${log4jVersion}"
    testImplementation 'org.slf4j:slf4j-simple:1.7.36'

    if (SAXON_TEST) {
        testRuntimeOnly "net.sf.saxon:Saxon-HE:${saxonVersion}"
    }

    broken("org.apache.xmlgraphics:batik-script:${batikVersion}"){
        exclude group: 'xalan', module: 'xalan'
        if (jdkVersion > 8) {
            exclude group: 'xml-apis', module: 'xml-apis'
        }
    }

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

final String MODULE_NAME = 'org.apache.poi.ooxml'
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() + files("build/brokenJars")

final String OOXML_LITE_AGENT = "../build/dist/maven/poi-ooxml-lite-agent/poi-ooxml-lite-agent-${project.version}.jar"
final String OOXML_LITE_REPORT = '../src/resources/ooxml-lite-report'
final String OOXML_LITE_INCLUDES = "^(com/microsoft/schemas|org/(etsi|openxmlformats|w3/)|org/apache/poi/schemas)"

compileJava {
    dependsOn 'fixBatik'
}

task compileJava9(type: JavaCompile) {
    dependsOn 'compileJava', ':poi:jar'

    javaCompiler = javaToolchains.compilerFor {
        languageVersion = JavaLanguageVersion.of(jdkVersion)
        if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
    }
    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
    ]

    onlyIf {
        jdkVersion > 8
    }
}

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

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

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

    javaCompiler = javaToolchains.compilerFor {
        languageVersion = JavaLanguageVersion.of(jdkVersion >= 17 ? 17 : 11)
        if (jdkVendor != '') vendor = JvmVendorSpec.matching(jdkVendor)
    }
    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()

    onlyIf {
        jdkVersion > 8
    }
}


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

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

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

    if (jdkVersion == 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 (jdkVersion == 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')
    }
}

// based on https://github.com/moditect/moditect-gradle-plugin/issues/12
task fixBatik(type: Zip) {
    ant.mkdir(dir: "${buildDir}/brokenJars")
    archiveFileName = "batik-script-${batikVersion}.jar"
    destinationDirectory = file("${buildDir}/brokenJars")
    from zipTree(configurations.broken.files.find{ f -> f.name.startsWith("batik-script") })
    filesMatching("**/org.apache.batik.script.InterpreterFactory") {
        it.filter{ it2 -> it2.contains("Rhino") ? "#" + it2 : it2 }
    }
}

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
        }
    }
}

javadocJar {
    metaInf {
        from("$projectDir/../legal/LICENSE")
        from("$projectDir/../legal/NOTICE")
    }
}

sourcesJar {
    metaInf {
        from("$projectDir/../legal/LICENSE")
        from("$projectDir/../legal/NOTICE")
    }
}

artifacts {
    tests testJar
}

test {
    // for some reason catching the OOM does not work when run from Gradle
    exclude '**/MemoryUsage.class'

    dependsOn { testJar }

    systemProperties['junit.jupiter.execution.parallel.enabled'] = 'true'

    if (NO_SCRATCHPAD) {
        useJUnitPlatform {
            excludeTags 'scratchpad.ignore'
        }
    }

    doFirst {
        jvmArgs += [
            "-Xverify:all",
            "-XX:ErrorFile=../build/hs_err_pid%p.log",
            "-javaagent:${OOXML_LITE_AGENT}=${OOXML_LITE_REPORT}|${OOXML_LITE_INCLUDES}"
        ]
        if (jdkVersion > 8) {
            jvmArgs += [
                '--add-modules', MODULE_NAME,
                '--module-path', '../build/dist/maven/poi-ooxml-tests' + File.pathSeparator + files(TEST_MODULE_PATH).asPath,
            ]
        }
    }
}

publishing {
    publications {
        POI(MavenPublication) {
            pom {
                name = 'Apache POI - API based on OPC and OOXML schemas'
                description = 'Apache POI - Java API To Access Microsoft Format Files'
            }
            suppressPomMetadataWarningsFor('renderApiElements')
            suppressPomMetadataWarningsFor('renderRuntimeElements')
            suppressPomMetadataWarningsFor('signingApiElements')
            suppressPomMetadataWarningsFor('signingRuntimeElements')
            suppressPomMetadataWarningsFor('rendersignApiElements')
            suppressPomMetadataWarningsFor('rendersignRuntimeElements')
        }
    }
}
