/* ====================================================================
   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.
==================================================================== */
buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }

    dependencies {
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
    }
}

plugins {
    id 'base'
    id("org.nosphere.apache.rat") version "0.7.0"
}

repositories {
    mavenCentral()
}

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

// 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.7.1")
    antLibs("org.apache.ant:ant-junitlauncher:1.10.9")
}

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

wrapper {
    // https://stackoverflow.com/a/54741656/2066598
    gradleVersion = '6.8'
}

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'

    version = '5.0.1-SNAPSHOT'
    ext {
        bouncyCastleVersion = '1.68'
        commonsCodecVersion = '1.15'
        commonsCompressVersion = '1.20'
        commonsMathVersion = '3.6.1'
        junitVersion = '5.7.1'
        log4jVersion = '2.14.0'
        mockitoVersion = '3.6.0'
        hamcrestVersion = '2.2'
        xmlbeansVersion = '5.0.0'
        batikVersion = '1.14'
    }

    tasks.withType(JavaCompile) {
        options.encoding = 'UTF-8'
    }

    tasks.withType(Jar) {
        duplicatesStrategy = 'fail'
    }

    sourceCompatibility = 1.8
    targetCompatibility = 1.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}"
    }

    jar {
        manifest {
            attributes 'Implementation-Title': 'Apache POI', 'Implementation-Version': project.version
        }
    }

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

        // 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 = "768m"

        // Specifying the local via system properties did not work, so we set them this way
        jvmArgs '-Duser.language=en -Duser.country=US'

        // 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['POI.testdata.path'] = '../test-data'

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

        systemProperties['junit.jupiter.execution.parallel.enabled'] = 'false'
    }

    jacoco {
        toolVersion = '0.8.6'
    }

    jacocoTestReport {
        reports {
            xml.enabled 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"
                property "sonar.coverage.jacoco.xmlReportPaths", "$projectDir/build/reports/jacoco/test/jacocoTestReport.xml"
            }
        }
    }

    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'

                pom {
                    packaging = 'jar'
                    url = 'https://poi.apache.org/'

                    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 asl = doc.createComment(new File('../legal/HEADER').text)
                        // adding ASF header before root node is ignored
                        // doc.insertBefore(asl, doc.getDocumentElement())
                        r.insertBefore(asl, r.getFirstChild())
                    }
                }
            }
        }
    }
}

// Make JavaDoc behave similar to Ant, i.e. be a bit more lenient
// and define amount of memory
// https://blog.joda.org/2014/02/turning-off-doclint-in-jdk-8-javadoc.html
if (JavaVersion.current().isJava8Compatible()) {
	allprojects {
		tasks.withType(Javadoc) {
			options.addStringOption('Xdoclint:none', '-quiet')
			maxMemory="384M"
		}
	}
}

// initial try to provide a combined JavaDoc, grouping is still missing here, though!
task allJavaDoc(type: Javadoc) {
	source subprojects.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="384M"

	// for possible options see https://docs.gradle.org/current/javadoc/org/gradle/external/javadoc/StandardJavadocDocletOptions.html
	options.use = true
	options.splitIndex = true

	title = 'POI API Documentation'
	options.bottom = '<![CDATA[<i>Copyright ' + new Date().format('yyyy') + ' The Apache Software Foundation or\n' +
			'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
jenkins.dependsOn allJavaDoc

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.add("poi-examples/**")
    includes.add("poi-excelant/**")
    includes.add("poi-integration/**")
    includes.add("legal/**")
    includes.add("poi/**")
    includes.add("maven/**")
    includes.add("poi-ooxml/**")
    includes.add("poi-ooxml-full/**")
    includes.add("poi-ooxml-lite/**")
    includes.add("poi-ooxml-lite-agent/**")
    //includes.add("osgi/**")
    includes.add("poi-scratchpad/**")
    includes.add("src/**")
    //includes.add("sonar/**")
    includes.add("build.*")

    // List of Gradle exclude directives, defaults to ['**/.gradle/**']
    //excludes.add("main/java/org/apache/poi/**/*-chart-data.txt")
    includes.add("build.javacheck.xml")
    excludes.add("**/build/**")
    excludes.add("**/out/**")
    excludes.add("**/*.iml")
    excludes.add("**/*.log")
    excludes.add("**/main/java/org/apache/poi/**/*-chart-data.txt")
    excludes.add("poi/src/main/resources/org/apache/poi/sl/draw/geom/presetShapeDefinitions.xml")
    excludes.add("poi-ooxml/src/main/resources/org/apache/poi/xslf/usermodel/notesMaster.xml")
    excludes.add("poi-ooxml/src/main/resources/org/apache/poi/xssf/usermodel/presetTableStyles.xml")
    excludes.add("poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/XAdES*.xsd")
    excludes.add("poi-ooxml-full/src/main/xmlschema/org/apache/poi/schemas/xmldsig-core-schema.xsd")
    excludes.add("poi-ooxml-full/src/main/xmlschema/org/apache/poi/xdgf/visio.xsd")
    /*
    <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 site(type:Exec) {
    doFirst {
        if (System.env.FORREST_HOME == null) {
            throw new InvalidUserDataException(
                'Apache Forrest is not installed.\n' +
                    'Please install Apache Forrest (see https://forrest.apache.org/index.html) and set the\n' +
                    'FORREST_HOME environment variable!')
        }

        if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
            // maybe Java 9-11 works too?
            throw new GradleException("Apache Forrest must be executed with Java 8!")
        }
    }

    if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
        commandLine 'cmd', '/c', "${System.env.FORREST_HOME}/bin/forrest.bat"
    } else {
        commandLine "${System.env.FORREST_HOME}/bin/forrest"
    }

    //store the output instead of printing to the console:
    standardOutput = new ByteArrayOutputStream()

    ext.output = {
        return standardOutput.toString()
    }

    doLast {
        println 'Broken links:'
        println file("${buildDir}/tmp/brokenlinks.xml").text

        /* Apache Forrest is dead, so we cannot expect fixes there however it does not handle "https" in "credits"
        currently if the *.xml file is in a sub-directory, see Apache Forrest code at
        main/webapp/skins/pelt/xslt/html/site-to-xhtml.xsl:350

        So we need to replace the links afterwards to have a fully "https" website and avoid browser warning about
        a "mixed content" website */
        def buildSite = "${buildDir}/site"

        println "Fix https in ${buildSite}"

        ant.replace(dir: buildSite, summary:'true', includes:'**/*.html',
            token:'http://www.apache.org/events/current-event-125x125.png',
            value:'https://www.apache.org/events/current-event-125x125.png')

        ant.replace(dir: buildSite, summary:'true', includes:'**/*.html',
            token:'http://www.google.com/search',
            value:'https://www.google.com/search')

        ant.fixcrlf(srcdir: buildSite, includes:'**/*.html,**/*.css', eol:'unix', eof:'remove')
    }
}
