/* ====================================================================
   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'
        exclude group: 'xml-apis', module: 'xml-apis'
    }

    compileClasspath {
        exclude group: 'xalan', module: 'xalan'
        exclude group: 'xml-apis', module: 'xml-apis'
    }

    broken
    tests
    javadocs
}

sourceSets {
    main {
        output.dir(JAVA9_OUT, builtBy: 'compileJava9')
    }
    test {
        output.dir(TEST9_OUT, builtBy: 'compileTest9')
    }
}

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.08'
    api "org.apache.logging.log4j:log4j-api:${log4jVersion}"
    api 'org.apache.commons:commons-collections4:4.4'

    signingImplementation "org.apache.santuario:xmlsec:${xmlSecVersion}"
    signingImplementation "org.bouncycastle:bcpkix-jdk18on:${bouncyCastleVersion}"
    signingImplementation "org.bouncycastle:bcutil-jdk18on:${bouncyCastleVersion}"

    rendersignImplementation "org.apache.santuario:xmlsec:${xmlSecVersion}"
    rendersignImplementation "org.bouncycastle:bcpkix-jdk18on:${bouncyCastleVersion}"
    rendersignImplementation "org.bouncycastle:bcutil-jdk18on:${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'
        exclude group: 'xml-apis', module: 'xml-apis'
    }
    renderImplementation("org.apache.xmlgraphics:batik-codec:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        exclude group: 'xml-apis', module: 'xml-apis'
    }
    renderImplementation("org.apache.xmlgraphics:batik-bridge:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        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'
        exclude group: 'xml-apis', module: 'xml-apis'
    }
    rendersignImplementation("org.apache.xmlgraphics:batik-codec:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        exclude group: 'xml-apis', module: 'xml-apis'
    }
    rendersignImplementation("org.apache.xmlgraphics:batik-bridge:${batikVersion}") {
        exclude group: 'xalan', module: 'xalan'
        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.10.0'
    testImplementation 'org.reflections:reflections:0.10.2'
    testImplementation 'org.openjdk.jmh:jmh-core:1.36'
    testImplementation 'org.openjdk.jmh:jmh-generator-annprocess:1.36'
    testImplementation 'com.google.guava:guava:32.1.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-slf4j2-impl:${log4jVersion}"
    testImplementation 'org.slf4j:slf4j-simple:2.0.13'

    broken("org.apache.xmlgraphics:batik-script:${batikVersion}"){
        exclude group: 'xalan', module: 'xalan'
        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', 'cleanupBatik'
}

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

    javaCompiler = javaToolchains.compilerFor {
        languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion))
    }
    sourceCompatibility = 1.9
    targetCompatibility = 1.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 compileTest9(type: JavaCompile) {
    dependsOn 'compileTestJava', ':poi:testJar'

    javaCompiler = javaToolchains.compilerFor {
        languageVersion = JavaLanguageVersion.of(Math.max(11, jdkVersion))
    }
    sourceCompatibility = 1.9
    targetCompatibility = 1.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()
}


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

    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")

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

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

task cleanupBatik(type: Delete) {
    // remove older files to avoid build failures because of duplicate modules
    delete fileTree("${buildDir}/brokenJars/").matching {
        include "*.jar"
        exclude "batik*-${batikVersion}.jar"
    }
}

javadoc {
    failOnError = true
    doFirst {
        options {
            if (jdkVersion > 8) 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 (jdkVersion == 8)  {
        systemProperties['sun.java2d.renderer'] = 'sun.java2d.marlin.MarlinRenderingEngine'
    }

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

cyclonedxBom {
    // includeConfigs is the list of configuration names to include when generating the BOM (leave empty to include every configuration)
    includeConfigs = ["runtimeClasspath"]
    // skipConfigs is a list of configuration names to exclude when generating the BOM
    //skipConfigs = ["compileClasspath", "testCompileClasspath"]
    // Specified the type of project being built. Defaults to 'library'
    projectType = "library"
    // Specified the version of the CycloneDX specification to use. Defaults to 1.4.
    schemaVersion = "1.4"
    // Boms destination directory (defaults to build/reports)
    destination = file("build/reports")
    // The file name for the generated BOMs (before the file format suffix). Defaults to 'bom'
    outputName = "poi-ooxml-${project.version}.bom"
    // The file format generated, can be xml, json or all for generating both
    outputFormat = "all"
    // Exclude BOM Serial Number
    includeBomSerialNumber = true
}
