/* ====================================================================
   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.3'
        classpath 'de.thetaphi:forbiddenapis:3.3'
    }
}

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.6"
    id 'com.github.jk1.dependency-license-report' version '2.0'
}

repositories {
    mavenCentral()
}

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.8.2")
    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.4'
}

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.8.2'
        log4jVersion = '2.17.2'
        mockitoVersion = '4.5.1'
        hamcrestVersion = '2.2'
        xmlbeansVersion = '5.0.3'
        batikVersion = '1.14'
        graphics2dVersion = '0.38'
        pdfboxVersion = '2.0.26'
        saxonVersion = '11.3'
        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.2.8'
            }
        }
    }

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

        onlyIf {
            (name != "compileJava9" && name != "compileTest9") // || jdkVersion > 8
        }
    }

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

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

    task wrapper(type: Wrapper){
        gradleVersion = '7.4'
    }

    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(Math.max(11,jdkVersion))
        }

        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/'
                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.7'
    }

    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' ]
        // forbiddenapis bundled signatures max supported version is 14
        // targetCompatibility = (JavaVersion.VERSION_14.isCompatibleWith(JavaVersion.current()) ? JavaVersion.current() : JavaVersion.VERSION_14)
    }

    forbiddenApisMain {
        signaturesFiles += files('../src/resources/devtools/forbidden-signatures-prod.txt')
    }

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

    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 = 'http://mail-archives.apache.org/mod_mbox/poi-user/'
                        }
                        mailingList {
                            name = 'POI Developer List'
                            subscribe = 'dev-subscribe@poi.apache.org'
                            unsubscribe = 'dev-unsubscribe@poi.apache.org'
                            archive = 'http://mail-archives.apache.org/mod_mbox/poi-dev/'
                        }
                    }

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

                    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/XAdES*.xsd",
        "poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/xmldsig-core-schema.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
