/* ====================================================================
   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 org.w3c.dom.Node
import org.w3c.dom.NodeList

import javax.xml.xpath.XPath
import javax.xml.xpath.XPathConstants
import javax.xml.xpath.XPathFactory

buildscript {
    repositories {
        maven { url 'https://plugins.gradle.org/m2/' }
        mavenCentral()
    }

    dependencies {
        classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
    }
}

plugins {
    id 'base'
    id 'com.dorongold.task-tree' version '2.1.0'
    id 'org.nosphere.apache.rat' version '0.7.1'
    id 'distribution'
    id "com.github.spotbugs" version '5.0.10'
    id 'de.thetaphi.forbiddenapis' version '3.3'
    id 'com.github.jk1.dependency-license-report' version '2.0'
}

repositories {
    mavenCentral()
    //maven { url 'https://repository.apache.org/content/repositories/staging' }
}

import com.github.jk1.license.render.*
import com.github.jk1.license.importer.*

licenseReport {

    // Select projects to examine for dependencies.
    // Defaults to current project and all its subprojects
    projects = [project] + project.subprojects

    // Adjust the configurations to fetch dependencies, e.g. for Android projects. Default is 'runtimeClasspath'
    configurations = ['runtimeClasspath']
    // Use 'ALL' to dynamically resolve all configurations:
    // configurations = ALL

    // Don't include artifacts of project's own group into the report
    excludeOwnGroup = true

    // Don't exclude bom dependencies.
    // If set to true, then all boms will be excluded from the report
    excludeBoms = false

    // Set custom report renderer, implementing ReportRenderer.
    // Yes, you can write your own to support any format necessary.
    renderers = [new XmlReportRenderer('third-party-libs.xml', 'Back-End Libraries')]
}

// Only add the plugin for Sonar if enabled
if (project.hasProperty('enableSonar')) {
    println 'Enabling Sonar support'
    apply plugin: 'org.sonarqube'
}

boolean isCIBuild = false;

// For help converting an Ant build to a Gradle build, see
// https://docs.gradle.org/current/userguide/ant.html

configurations {
    antLibs {
        attributes {
            attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
        }
    }
}

dependencies {
    antLibs("org.junit.jupiter:junit-jupiter:5.9.0")
    antLibs("org.apache.ant:ant-junitlauncher:1.10.12")
}

ant.taskdef(name: "junit",
        classname: "org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask",
        classpath: configurations.antLibs.asPath)


wrapper {
    gradleVersion = '7.5'
}

task adjustWrapperPropertiesFile {
    doLast {
        ant.replaceregexp(match:'^#.*', replace:'', flags:'g', byline:true) {
            fileset(dir: project.projectDir, includes: 'gradle/wrapper/gradle-wrapper.properties')
        }
        new File(project.projectDir, 'gradle/wrapper/gradle-wrapper.properties').with { it.text = it.readLines().findAll { it }.sort().join('\n') }
        ant.fixcrlf(file: 'gradle/wrapper/gradle-wrapper.properties', eol: 'lf')
    }
}
wrapper.finalizedBy adjustWrapperPropertiesFile

/**
 Define properties for all projects, including this one
 */
allprojects {
//    apply plugin: 'eclipse'
    apply plugin: 'idea'
}

/**
 Define things that are only necessary in sub-projects, but not in the master-project itself
 */
subprojects {
    //Put instructions for each sub project, but not the master
    apply plugin: 'java-library'
    apply plugin: 'jacoco'
    apply plugin: 'maven-publish'
    apply plugin: 'signing'
    apply plugin: 'de.thetaphi.forbiddenapis'
    apply plugin: 'com.github.spotbugs'

    version = '5.2.3-SNAPSHOT'
    ext {
        bouncyCastleVersion = '1.70'
        commonsCodecVersion = '1.15'
        commonsCompressVersion = '1.21'
        commonsIoVersion = '2.11.0'
        commonsMathVersion = '3.6.1'
        junitVersion = '5.9.0'
        log4jVersion = '2.18.0'
        mockitoVersion = '4.7.0'
        hamcrestVersion = '2.2'
        xmlbeansVersion = '5.1.1'
        batikVersion = '1.14'
        graphics2dVersion = '0.38'
        pdfboxVersion = '2.0.26'
        saxonVersion = '11.4'
        apiGuardianVersion = '1.1.2'

        jdkVersion = (project.properties['jdkVersion'] ?: '8') as int
        // see https://github.com/gradle/gradle/blob/master/subprojects/jvm-services/src/main/java/org/gradle/internal/jvm/inspection/JvmVendor.java
        jdkVendor = (project.properties['jdkVendor'] ?: '') as String

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

        NO_SCRATCHPAD = (findProperty("scratchpad.ignore") == "true")
        SAXON_TEST = (findProperty("saxon.test") == "true")
    }

    configurations {
        all {
            resolutionStrategy {
                force "commons-io:commons-io:${commonsIoVersion}"
                force 'org.slf4j:slf4j-api:1.7.36'
                force 'com.fasterxml.woodstox:woodstox-core:6.3.1'
            }
        }
    }

    tasks.withType(JavaCompile) {
        options.encoding = 'UTF-8'
        options.compilerArgs << '-Xlint:unchecked'
        options.deprecation = true
        options.incremental = true
    }

    repositories {
        mavenCentral()
        maven { url 'https://repository.apache.org/content/repositories/staging' }
    }

    dependencies {
        testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}"
        testImplementation "org.mockito:mockito-core:${mockitoVersion}"
        testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
        testImplementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
    }

    java {
        toolchain {
            languageVersion.set(JavaLanguageVersion.of(jdkVersion))
            if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
        }
        withJavadocJar()
        withSourcesJar()
    }

    javadoc {
        failOnError = true
        maxMemory = "1024M"
        javadocTool = javaToolchains.javadocToolFor {
            languageVersion = JavaLanguageVersion.of(jdkVersion >= 17 ? 17 : 11)
        }

        doFirst {
            options {
                addBooleanOption('html5', true)
                addBooleanOption('Xdoclint:all,-missing', true)
                links 'https://poi.apache.org/apidocs/dev/'
                links 'https://docs.oracle.com/javase/8/docs/api/'
                links 'https://xmlbeans.apache.org/docs/5.0.0/'
                links 'https://commons.apache.org/proper/commons-compress/apidocs/'
                use = true
                splitIndex = true
                source = "1.8"
            }
        }
    }

    // helper-target to get a directory with all third-party libraries
    // this is used for mass-regression-testing
    task getDeps(type: Copy) {
        from sourceSets.main.runtimeClasspath
        into 'build/runtime/'
    }

    tasks.withType(Jar) {
        duplicatesStrategy = 'fail'
        destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}")

        doLast {
            ant.checksum(file: it.archivePath, algorithm: 'SHA-256', fileext: '.sha256', format: 'MD5SUM')
            ant.checksum(file: it.archivePath, algorithm: 'SHA-512', fileext: '.sha512', format: 'MD5SUM')
        }
    }

    jar {
        from("../legal") {
            include "NOTICE"
            include "LICENSE"
        }

        rename('^(NOTICE|LICENSE)', 'META-INF/$1')

        manifest {
            attributes(
                'Specification-Title': 'Apache POI',
                'Specification-Version': project.version,
                'Specification-Vendor': 'The Apache Software Foundation',
                'Implementation-Title': 'Apache POI',
                'Implementation-Version': project.version,
                'Implementation-Vendor': 'org.apache.poi',
                'Implementation-Vendor-Id': 'The Apache Software Foundation'
            )
        }
    }

    javadocJar {
        // if javadocs and binaries are in the same directory, JPMS complaints about duplicated modules
        // in the module-path
        destinationDirectory = file("../build/dist/maven/${project.archivesBaseName}-javadoc")
    }

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

    test {
        // make XML test-results available for Jenkins CI
        useJUnitPlatform()
        reports {
            junitXml.required = true
        }

        javaLauncher = javaToolchains.launcherFor {
            languageVersion.set(JavaLanguageVersion.of(jdkVersion))
            if (jdkVendor != '') vendor.set(JvmVendorSpec.matching(jdkVendor))
        }

        // Exclude some tests that are not actually tests or do not run cleanly on purpose
        exclude '**/BaseTestBorderStyle.class'
        exclude '**/BaseTestCellUtil.class'
        exclude '**/TestUnfixedBugs.class'
        exclude '**/TestOneFile.class'

        // Exclude Test Suites
        exclude '**/All*Tests.class'
        exclude '**/HSSFTests.class'

        // set heap size for the test JVM(s)
        minHeapSize = "128m"
        maxHeapSize = "1G"


        // Specifying the local via system properties did not work, so we set them this way
        jvmArgs << [
            '-Djava.awt.headless=true',
            '-Djavax.xml.stream.XMLInputFactory=com.sun.xml.internal.stream.XMLInputFactoryImpl',
            "-Dversion.id=${project.version}",
            '-ea',
            // -Xjit:verbose={compileStart|compileEnd},vlog=build/jit.log${no.jit.sherlock}   ... if ${isIBMVM}
        ]

        // detect if running on Jenkins/CI
        isCIBuild |= Boolean.valueOf(System.getenv("CI_BUILD"));

        if (isCIBuild) {
            System.out.println("Run with reduced parallelism for CI build");

            jvmArgs += [
                // Strictly serial
                // '-Djunit.jupiter.execution.parallel.enabled=false',

                // OR parallel on 2 threads
                '-Djunit.jupiter.execution.parallel.config.strategy=fixed',
                '-Djunit.jupiter.execution.parallel.config.fixed.parallelism=2'
            ]
            maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
        } else {
            jvmArgs += [
                '-Djunit.jupiter.execution.parallel.enabled=true',
                '-Djunit.jupiter.execution.parallel.config.strategy=dynamic',

                // this setting breaks the test builds, do not use it!
                //'-Djunit.jupiter.execution.parallel.mode.default=concurrent'
            ]

             // Explicitly defining the maxParallelForks was always slower than not setting it
             // So we leave this to Gradle itself, which seems to be very smart
             // maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
             // maxParallelForks = Math.max( Runtime.runtime.availableProcessors() - 1, 1 )
        }

        // show standard out and standard error of the test JVM(s) on the console
        //testLogging.showStandardStreams = true

        // http://forums.gradle.org/gradle/topics/jacoco_related_failure_in_multiproject_build
        systemProperties['user.dir'] = workingDir
        systemProperties['java.io.tmpdir'] = 'build'

        systemProperties['POI.testdata.path'] = '../test-data'

        // define the locale to not have failing tests when the locale is set differently on the current machine
        systemProperties['user.language'] = 'en'
        systemProperties['user.country'] = 'US'

        // this is necessary for JDK 9+ to keep formatting dates the same way as in previous JDK-versions
        systemProperties['java.locale.providers'] = 'JRE,CLDR'

        doFirst {
            if (jdkVersion > 8) {
                // some options were removed in JDK 18
                if (jdkVersion < 18) {
                    jvmArgs += [
                        '--illegal-access=warn',
                    ]
                }

                jvmArgs += [
                    // 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=org.apache.poi.poi',
                    '--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',

                    '-Dsun.reflect.debugModuleAccessChecks=true',
                    '-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true',
                ]
            }
        }

        jacoco {
            excludes = [
                // this is necessary to make JaCoCo work with JDK 18 for now
                'sun/**',
                'javax/**',
            ]
        }
    }

    jacoco {
        toolVersion = '0.8.8'
    }

    jacocoTestReport {
        reports {
            xml.required = true
        }
    }

    // ensure the build-dir exists
    projectDir.mkdirs()

    if (project.hasProperty('enableSonar')) {
        // See https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/ and
        // https://docs.sonarqube.org/display/SONARQUBE52/Analyzing+with+SonarQube+Scanner+for+Gradle
        // for documentation of properties.
        //
        // Some additional properties are currently set in the Jenkins-DSL, see jenksin/create_jobs.groovy
        //
        sonarqube {
            properties {
                // as we currently use build/<module>/ as project-basedir, we need to tell Sonar to use
                // the root-folder as "basedir" for the projects
                property "sonar.projectBaseDir", "$projectDir"
                // currently supported providers on Jenkins: "hg,git": property "sonar.scm.provider", "svn"

                // the plugin seems to not detect our non-standard build-layout
                property "sonar.junit.reportPaths", "$projectDir/build/test-results/test"

                // the Gradle run will report an invalid directory for 'ooxml-schema', but it seems to still work fine
                property "sonar.coverage.jacoco.xmlReportPaths", "$projectDir/build/reports/jacoco/test/jacocoTestReport.xml"

                // somehow the version was not use properly
                property "sonar.projectVersion", version
            }
        }
    }

    forbiddenApis {
        bundledSignatures = [ 'jdk-unsafe', 'jdk-deprecated', 'jdk-internal', 'jdk-non-portable', 'jdk-reflection' ]
        signaturesFiles = files('../src/resources/devtools/forbidden-signatures.txt')
        ignoreFailures = false
        suppressAnnotations = [ 'org.apache.poi.util.SuppressForbidden' ]
    }

    forbiddenApisTest {
        // forbiddenapis bundled signatures max supported version is 17
        // also see https://github.com/policeman-tools/forbidden-apis/issues/191
        targetCompatibility = (JavaVersion.VERSION_17.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_17)
    }

    forbiddenApisMain {
        signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt')
        targetCompatibility = (JavaVersion.VERSION_17.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_17)
    }

    task jenkins
    jenkins.dependsOn build
    jenkins.dependsOn check
    jenkins.dependsOn javadoc
    jenkins.dependsOn jacocoTestReport
    jenkins.dependsOn rat
    jenkins.dependsOn getDeps

    publishing {
        publications {
            POI(MavenPublication) {
                groupId 'org.apache.poi'
                artifactId project.archivesBaseName

                from components.java

                pom {
                    packaging = 'jar'
                    url = 'https://poi.apache.org/'
                    name = 'Apache POI'
                    description = 'Apache POI - Java API To Access Microsoft Format Files'

                    mailingLists {
                        mailingList {
                            name = 'POI Users List'
                            subscribe = 'user-subscribe@poi.apache.org'
                            unsubscribe = 'user-unsubscribe@poi.apache.org'
                            archive = 'https://lists.apache.org/list.html?user@poi.apache.org'
                        }
                        mailingList {
                            name = 'POI Developer List'
                            subscribe = 'dev-subscribe@poi.apache.org'
                            unsubscribe = 'dev-unsubscribe@poi.apache.org'
                            archive = 'https://lists.apache.org/list.html?dev@poi.apache.org'
                        }
                    }

                    licenses {
                        license {
                            name = 'Apache License, Version 2.0'
                            url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                            distribution = 'repo'
                        }
                    }

                    organization {
                        name = 'Apache Software Foundation'
                        url = 'http://www.apache.org/'
                    }

                    issueManagement {
                        system = 'bugzilla'
                        url = 'https://bz.apache.org/bugzilla'
                    }

                    developers {
                        developer {
                            name = 'POI Team'
                            id = 'poi'
                            email = 'user@poi.apache.org'
                            organization = 'Apache POI'
                        }
                    }

                    withXml {
                        def r = asElement()
                        def doc = r.getOwnerDocument()
                        def hdr = new File('../legal/HEADER')
                        if (!hdr.exists()) hdr = new File('legal/HEADER')
                        def asl = doc.createComment(hdr.text)
                        // adding ASF header before root node is ignored
                        // doc.insertBefore(asl, doc.getDocumentElement())
                        r.insertBefore(asl, r.getFirstChild())

                        // Replace ooxml-full with ooxml-lite
                        XPath xpath = XPathFactory.newInstance().newXPath()
                        NodeList res = (NodeList)xpath.evaluate("//dependency/artifactId[text() = 'poi-ooxml-full']", doc, XPathConstants.NODESET)
                        for (int i=res.getLength()-1; i>=0; i--) {
                            res.item(i).setTextContent('poi-ooxml-lite')
                        }

                        // remove duplicate entries
                        res = (NodeList)xpath.evaluate("//dependency[artifactId = ./preceding-sibling::dependency/artifactId]", doc, XPathConstants.NODESET)
                        for (int i=res.getLength()-1; i>=0; i--) {
                            Node n = res.item(i)
                            n.getParentNode().removeChild(n)
                        }
                    }
                }
            }
        }
    }

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

    tasks.withType(GenerateModuleMetadata) {
        enabled = false
    }

    signing {
        setRequired {
            // signing is only required if this is a release version
            // and the artifacts are to be published
            gradle.taskGraph.allTasks.any { it instanceof PublishToMavenRepository }
        }
        sign publishing.publications.POI
    }
    signPOIPublication.dependsOn('generatePomFileForPOIPublication')

    spotbugs {
        ignoreFailures = true
        showStackTraces = false
    }

    build {
        if (project.hasProperty('signing.keyId')) {
            dependsOn 'signPOIPublication'
        }
    }
}

// initial try to provide a combined JavaDoc, grouping is still missing here, though!
task allJavaDoc(type: Javadoc) {
    var prj = [ project(':poi'), project(':poi-excelant'), project(':poi-ooxml'), project(':poi-scratchpad') ]
    source prj.collect { it.sourceSets.main.allJava }

    // for possible settings see https://docs.gradle.org/current/dsl/org.gradle.api.tasks.javadoc.Javadoc.html
    classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath })
    destinationDir = file("${buildDir}/docs/javadoc")
    maxMemory="2048M"

    // for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html
    options.use = true
    options.splitIndex = true
    options.addBooleanOption('Xdoclint:all,-missing', true)

    title = 'POI API Documentation'
    options.bottom = '<![CDATA[<i>Copyright ' + new Date().format('yyyy') + ' The Apache Software Foundation or its licensors, as applicable.</i>]]>'

    options.group('DDF - Dreadful Drawing Format', 'org.apache.poi.ddf*')
    options.group('HPSF - Horrible Property Set Format', 'org.apache.poi.hpsf*')
    options.group('SS - Common Spreadsheet Format', 'org.apache.poi.ss*')
    options.group('HSSF - Horrible Spreadsheet Format', 'org.apache.poi.hssf*')
    options.group('XSSF - Open Office XML Spreadsheet Format', 'org.apache.poi.xssf*')
    options.group('SL - Common Slideshow Format',  'org.apache.poi.sl*')
    options.group('HSLF - Horrible Slideshow Format', 'org.apache.poi.hslf*', 'org.apache.poi.hwmf*', 'org.apache.poi.hemf*')
    options.group('XSLF - Open Office XML Slideshow Format', 'org.apache.poi.xslf*')
    options.group('HWPF - Horrible Word Processor Format', 'org.apache.poi.hwpf*')
    options.group('XWPF - Open Office XML Word Processor Format', 'org.apache.poi.xwpf*')
    options.group('HDGF - Horrible Diagram Format', 'org.apache.poi.hdgf*')
    options.group('XDGF - Open Office XML Diagram Format', 'org.apache.poi.xdgf*')
    options.group('HMEF - Transport Neutral Encoding Files (TNEF)', 'org.apache.poi.hmef*')
    options.group('HSMF Outlook message file format', 'org.apache.poi.hsmf*')
    options.group('HPBF - Publisher Format Files', 'org.apache.poi.hpbf*')
    options.group('POIFS - POI File System', 'org.apache.poi.poifs*')
    options.group('Utilities', 'org.apache.poi.util*')
    options.group('Excelant', 'org.apache.poi.ss.excelant**')
//  options.group('Examples', 'org.apache.poi.examples*')
}


task jenkins(dependsOn: ['replaceVersion', subprojects.build, 'binDistZip','binDistTar','srcDistZip','srcDistTar']) {}

clean {
    delete "${rootDir}/build/dist"
}

rat {
    // Input directory, defaults to '.'
    inputDir.set(file("."))

    // include all directories which contain files that are included in releases
    includes = [
        "poi-examples/**",
        "poi-excelant/**",
        "poi-integration/**",
        "legal/**",
        "poi/**",
        "maven/**",
        "poi-ooxml/**",
        "poi-ooxml-full/**",
        "poi-ooxml-lite/**",
        "poi-ooxml-lite-agent/**",
        "osgi/**",
        "poi-scratchpad/**",
        "src/**",
    //    "sonar/**",
        "build.*"
    ]

    // List of Gradle exclude directives, defaults to ['**/.gradle/**']
    //excludes.add("main/java/org/apache/poi/**/*-chart-data.txt")
    excludes = [
        "build.javacheck.xml",
        "**/build/**",
        "**/out/**",
        "**/*.iml",
        "**/*.log",
        "**/gradle-wrapper.properties",
        "**/main/java/org/apache/poi/**/*-chart-data.txt",
        "poi/src/main/resources/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml",
        "poi-ooxml/src/main/resources/org/apache/poi/xslf/usermodel/notesMaster.xml",
        "poi-ooxml/src/main/resources/org/apache/poi/xssf/usermodel/presetTableStyles.xml",
        "poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/*.xsd",
        "poi-ooxml-full/src/main/xmlschema/org/apache/poi/xdgf/visio.xsd",
        "osgi/README.md",
        "src/resources/ooxml-lite-report.*",
        // ignore svn conflict artifacts
        "**/module-info.*"
    ]

    /*
    <exclude name="documentation/*.txt" />
    <exclude name="documentation/content/xdocs/dtd/" />
    <exclude name="documentation/content/xdocs/entity/" />
    <exclude name="documentation/resources/images/pb-poi.cdr"/>
    */

    // Prints the list of files with unapproved licences to the console, defaults to false
    verbose.set(true)
}

/*task downloadJarsToLibs() {
    def f = new File("$projectDir/../lib/ooxml/xmlbeans-5.0.0.jar")
    if (!f.exists()) {
    println 'writing file ' + f.getAbsolutePath()
    f.getParentFile().mkdirs()
    new URL('https://ci-builds.apache.org/job/POI/job/POI-XMLBeans-DSL-1.8/lastSuccessfulBuild/artifact/build/xmlbeans-5.0.0.jar').withInputStream{ i -> f.withOutputStream{ it << i }}
    }
}*/

//compileJava.dependsOn 'downloadJarsToLibs'

task replaceVersion() {
    outputs.upToDateWhen { false }

    var version = subprojects[0].version
    var tokens = [
        [ 'osgi', 'pom.xml', '(packaging>\\n\\s*<version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ],
        [ 'osgi', 'pom.xml', '(<poi.version>)[0-9.]+(?:-SNAPSHOT|-RC\\d+)?', "\\1${version}" ]
        // [ '.', 'build.gradle', ' version = \'[0-9.]+(?:-SNAPSHOT)?\'', " version = '${version}'" ]
    ]

    doLast {
        tokens.forEach {
            var dir = it[0], name = it[1], match = it[2], replace = it[3]
            ant.replaceregexp(match: match, replace: replace) {
                fileset(dir: dir) {
                    include(name: name)
                }
            }
        }
    }
}

task zipJavadocs(type: Zip, dependsOn: allJavaDoc) {
    from('build/docs/javadoc/')
    destinationDirectory = file('build/dist')
    archiveBaseName = 'poi'
    archiveVersion = subprojects[0].version
    archiveAppendix = 'javadoc'
    archiveExtension = 'jar'
}

tasks.withType(Tar) {
    compression = Compression.GZIP
    archiveExtension = 'tgz'
}

distributions {
    var version = subprojects[0].version
    var date = new Date().format('yyyyMMdd')

    var poiDep = project(':poi').configurations.getAt('compileClasspath')
    var ooxmlImp = project(':poi-ooxml').configurations.getAt('compileClasspath')

    bin {
        distributionBaseName = "poi-bin-${version}-${date}"
        contents {
            from('build/dist/maven') {
                include "**/*${version}.jar"
                exclude "**/*lite-agent*.jar"
                exclude "**/*integration*.jar"
            }

            from('build/dist') { include 'poi-javadoc*.jar'}
            from('legal') { exclude 'HEADER' }
            from(poiDep) { include "**/*.jar" }
            from(ooxmlImp) { include "**/*.jar" }

            includeEmptyDirs = false
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE

            eachFile {
                String root = "poi-bin-${version}/"
                if (name.startsWith('poi')) {
                    path = root + name
                } else if (poiDep.contains(file)) {
                    path = root + 'lib/' + name
                } else if (name =~ /^(batik|bc|fontbox|graphics|pdfbox|xml-apis|xmlgraphics|xmlsec)/) {
                    path = root + 'auxiliary/' + name
                } else if (ooxmlImp.contains(file)) {
                    path = root + 'ooxml-lib/' + name
                } else {
                    path = root + name
                }
            }
        }
    }

    src {
        distributionBaseName = "poi-src-${version}-${date}"
        contents {
            from('.') {
                exclude '*/build/**'
                exclude 'build/**'
                exclude 'dist*/**'
                exclude 'lib/**'
                exclude 'lib.stored/**'
                exclude 'bin/**'
                exclude 'out/**'
                exclude 'tmp/**'
                exclude 'gradle/**'
                exclude 'sonar/**/target/**'
                exclude 'sonar/*/src/**'
                exclude 'compile-lib/**'
                exclude 'ooxml-lib/**'
                exclude 'ooxml-testlib/**'
                exclude 'scripts/**'
                exclude '.gradle/**'
                exclude '.idea/**'
                exclude '.classpath'
                exclude '.settings/**'
                exclude '.project'
                exclude 'TEST*'
                exclude 'gradlew'
                exclude 'gradlew.bat'
                exclude '**/*.iml'
                exclude '*.ipr'
                exclude '*.iws'
                exclude '*.rdf'
                exclude '*.png'
                exclude '*.gif'
                exclude '*.jpg'
                exclude '*.jpeg'
                exclude '*.swp'
                exclude '*.lnk'
                exclude '*.log'
                exclude '*.launch'
                exclude '*.docx'
                exclude '*.pptx'
                exclude '*.xlsx'

                // exclude intermediate files
                exclude '**/*-saved.xls'
            }
            from('legal') { exclude 'HEADER' }
        }
    }
}

binDistZip.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'
binDistTar.dependsOn 'zipJavadocs', ':poi-ooxml-lite:jar'

task soLinkCheck() {
    doLast {
        def path = ant.path {
            fileset(dir: '.', includes: '**/*.java') {
                exclude(name: 'build.gradle')
                contains(text: 'stackoverflow.com')
            }
        }

        path.list().each {
            println it
        }

        if (path.size() > 0) {
            // #65796 - minimize notifications about non-asf open source
            throw new GradleException('License issue found - conceal the link and contradict any findings m(')
        }
    }
}

var srcDep = [
    ':poi:cacheJava9',
    ':poi:cacheTest9',
    ':poi-ooxml-full:cacheJava9',
    ':poi-ooxml-lite-agent:cacheJava9',
    ':poi-ooxml:cacheJava9',
    ':poi-ooxml:cacheTest9',
    ':poi-scratchpad:cacheJava9',
    ':poi-scratchpad:cacheTest9',
    ':poi-excelant:cacheJava9',
    ':poi-excelant:cacheTest9',
    ':poi-examples:cacheJava9',
    ':poi-integration:cacheTest9',
    ':poi-ooxml-lite:cacheJava9',
    ':poi-ooxml-lite:generateModuleInfo'
]

srcDistTar.dependsOn srcDep
srcDistZip.dependsOn srcDep
soLinkCheck.dependsOn srcDep
rat.dependsOn soLinkCheck

task fixDistDir {
    doLast {
        ant.mkdir(dir: 'build/dist')
        ant.move(todir: 'build/dist') {
            fileset(dir: 'build/distributions', includes: '*')
        }
    }
}

binDistZip.finalizedBy fixDistDir
binDistTar.finalizedBy fixDistDir
srcDistZip.finalizedBy fixDistDir
srcDistTar.finalizedBy fixDistDir
