/*
 * 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 at.bxm.gradleplugins.svntools.tasks.SvnCheckout
import org.apache.tools.ant.filters.ReplaceTokens
import org.asciidoctor.gradle.jvm.AsciidoctorTask

/* ========================================================
 * Project setup
 * ======================================================== */
plugins {
    id 'application'
    id 'groovy'
    id 'eclipse'
    id 'checkstyle'
    id 'codenarc'
    id 'maven-publish'
    id 'at.bxm.svntools' version '3.1'
    id 'org.asciidoctor.jvm.convert' version '3.3.2'
    id 'org.asciidoctor.jvm.pdf' version '3.3.2'
    id 'org.owasp.dependencycheck' version '7.4.4' apply false
    id 'se.patrikerdes.use-latest-versions' version '0.2.18' apply false
    id 'com.github.ben-manes.versions' version '0.42.0' apply false
    id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
    id "com.github.jakemarsden.git-hooks" version "0.0.2"
    id "com.github.node-gradle.node" version '3.5.1' apply false
}

/* OWASP plugin
 *
 * If project property "enableOwasp" is flagged then
 * gradle will download required dependencies and
 * activate Gradle's OWASP plugin and its related tasks.
 *
 * Syntax: gradlew -PenableOwasp dependencyCheckAnalyze
 */
if (project.hasProperty('enableOwasp')) {
    apply plugin: 'org.owasp.dependencycheck'
}

/* DependencyUpdates plugin
 *
 * If project property "enableDependencyUpdates" is flagged then
 * gradle will download required dependencies and
 * activate Gradle's DependencyUpdates plugin and its related tasks.
 *
 * Syntax: gradlew -PenableDependencyUpdates dependencyUpdates -Drevision=release
 *
 * You may want to use the use-latest-versions plugin to help you in your work
 * Syntax:
 *  Check only: gradlew -PenableDependencyUpdates useLatestVersions && gradlew -PenableDependencyUpdates useLatestVersionsCheck
 *  Automated update: gradlew -PenableDependencyUpdates useLatestVersions
 *  Beware that this is only a help.
 *  If you use it without check you will need to check things by yourself (can be as tedious as not using this plugin)
 */
if (project.hasProperty('enableDependencyUpdates')) {
    apply plugin: 'com.github.ben-manes.versions'
    apply plugin: 'se.patrikerdes.use-latest-versions'
}

apply from: 'common.gradle'

// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.gradlew = os.contains('windows') ? 'gradlew.bat' : './gradlew'
ext.pluginsDir = "${rootDir}/plugins"

application {
    mainClassName = 'org.apache.ofbiz.base.start.Start'
    applicationDefaultJvmArgs = project.hasProperty('jvmArgs')
            ? jvmArgs.tokenize()
            : ['-Xms128M','-Xmx1024M',
            '-Djdk.serialFilter=maxarray=100000;maxdepth=20;maxrefs=1000;maxbytes=500000', // OFBIZ-12592 and OFBIZ-12716
            '--add-exports=java.base/sun.util.calendar=ALL-UNNAMED', // OFBIZ-12721
            '--add-opens=java.base/java.util=ALL-UNNAMED' // OFBIZ-12726
            ]
}

distributions.main.contents.from(rootDir) {
    include 'framework/**', 'applications/**', 'themes/**', 'plugins/**'
}

javadoc {
    title="OFBiz " + getCurrentGitBranch() + " API"
    failOnError = true
    options {
        source '17'
        encoding 'UTF-8'
        charSet 'UTF-8'
        // Those external Javadoc links should correspond to the actual
        // versions declared in the 'dependencies' block.
        links(
            'https://docs.oracle.com/javase/17/docs/api',
            'https://tomcat.apache.org/tomcat-9.0-doc/servletapi/',
            'http://docs.groovy-lang.org/docs/groovy-3.0.13/html/api',
            'https://commons.apache.org/proper/commons-cli/apidocs'
        )
    }
}

java {
    sourceCompatibility(JavaVersion.VERSION_17)
    targetCompatibility(JavaVersion.VERSION_17)
}

// Java compile options, syntax gradlew -PXlint:none build
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    if (!project.hasProperty('Xlint:none')) {
        options.compilerArgs << '-Xlint:all'
        // Exclude varargs warnings which are not silenced by @SafeVarargs.
        options.compilerArgs << '-Xlint:-varargs'
    }
}

// Only used for release branches
def getCurrentGitBranch() {
    return "git branch --show-current".execute().text.trim()
}

// defines the footer files for git info
def File gitFooterFile = file("${rootDir}/runtime/GitInfo.ftl")

// root and subproject settings
defaultTasks 'jar', 'test'

allprojects {
    repositories {
        mavenCentral()
        // the switch from jCenter to mavenCentral needs some additional repositories to be configured here
        // this should be checked frequently to remove obsolete configurations if the artifacts are available
        // on mavenCentral directly
        maven {
            // org.restlet and org.restlet.ext.servlet
            url 'https://maven.restlet.talend.com'
        }
        maven {
            // net.fortuna.ical4j:ical4j:1.0-rc3-atlassian-11
            url 'https://packages.atlassian.com/maven-3rdparty/'
        }
        maven {
            // org/milyn/flute/1.3/flute-1.3.jar
            // need artifact only because of wrong pom metadata in maven central
            // Required by: plugins:birt > org.eclipse.birt.runtime:viewservlets:4.5.0 > org.eclipse.birt.runtime:org.eclipse.birt.runtime:4.4.1
            // TODO Maybe this will no longer needed wheh upgrading viewservlets to 4.9.0
            url "https://repo1.maven.org/maven2"
            metadataSources {
                artifact()
            }
        }
        maven {
            url 'https://clojars.org/repo'
        }
        maven {
            // org.cyberneko.html.parsers (used by UELFunctions, was in esapi before 2.3)
            url "https://repository.ow2.org/nexus/content/repositories/public/"
        }

    }
}

subprojects {
    configurations {
        // compile-time plugin libraries
        pluginLibsCompile
        // runtime plugin libraries
        pluginLibsRuntime
        //compile-only libraries
        pluginLibsCompileOnly
    }
}

configurations {
    junitReport {
        description = 'libraries needed to run junitreport for OFBiz unit tests'
    }
    ofbizPlugins {
        description = 'ofbiz plugin dependencies configuration'
        transitive = true
    }
}

configurations.all {
    exclude group: 'log4j', module: 'log4j'
    exclude group: 'org.slf4j', module: 'slf4j-log4j12'
    exclude group: 'xml-apis', module: 'xml-apis'
    exclude group: 'jaxen', module: 'jaxen'
    exclude group: 'javax.xml.stream', module: 'stax-api'
    exclude group: 'org.apache.geronimo.specs', module: 'geronimo-stax-api_1.0_spec'
    exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jta_1.1_spec'
    exclude group: 'javax.transaction', module: 'jta'
}

dependencies {
    implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'
    implementation 'com.google.zxing:core:3.5.1'
    implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
    implementation 'com.googlecode.ez-vcard:ez-vcard:0.11.3'
    implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20220608.1'
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.57'
    implementation 'com.ibm.icu:icu4j:72.1'
    implementation ('com.lowagie:itext:2.1.7') { // Don't update due to license change in newer versions, see OFBIZ-10455
        exclude  group: 'bouncycastle', module: 'bcmail-jdk14'
        exclude  group: 'bouncycastle', module: 'bcprov-jdk14'
        exclude  group: 'bouncycastle', module: 'bctsp-jdk14'
    }
    implementation 'com.sun.mail:javax.mail:1.6.2'
    implementation 'com.rometools:rome:1.18.0'
    implementation 'com.thoughtworks.xstream:xstream:1.4.19'
    implementation 'commons-cli:commons-cli:1.5.0'
    implementation 'commons-fileupload:commons-fileupload:1.5'
    implementation 'commons-net:commons-net:3.8.0'
    implementation 'commons-validator:commons-validator:1.7'
    implementation 'de.odysseus.juel:juel-impl:2.2.7'
    implementation 'javax.transaction:javax.transaction-api:1.3'
    implementation 'net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12'
    implementation 'net.lingala.zip4j:zip4j:2.11.2'
    implementation 'org.apache.ant:ant-junit:1.10.12'
    implementation 'org.apache.commons:commons-collections4:4.4'
    implementation 'org.apache.commons:commons-csv:1.9.0'
    implementation 'org.apache.commons:commons-dbcp2:2.9.0'
    implementation 'org.apache.commons:commons-imaging:1.0-alpha3' // Alpha but OK, "Imaging was working and was used by a number of projects in production even before reaching its initial release as an Apache Commons component."
    implementation 'org.apache.commons:commons-text:1.10.0'
    implementation 'org.apache.geronimo.components:geronimo-transaction:3.1.5'
    implementation 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13'
    implementation 'org.apache.logging.log4j:log4j-api:2.19.0' // the API of log4j 2
    implementation 'org.apache.logging.log4j:log4j-core:2.19.0' // Somehow needed by Buildbot to compile OFBizDynamicThresholdFilter.java
    implementation 'org.apache.poi:poi:4.1.2' // poi-ooxml-schemas-5.0.0.pom'. Received status code 401 from server
    implementation 'org.apache.pdfbox:pdfbox:2.0.27'
    implementation 'org.apache.shiro:shiro-core:1.10.1'
    implementation 'org.apache.sshd:sshd-core:2.9.1'
    implementation 'org.apache.sshd:sshd-sftp:2.9.1'
    implementation 'org.apache.tika:tika-core:2.5.0'
    implementation 'org.apache.tika:tika-parsers:2.5.0'
    implementation 'org.apache.tika:tika-parser-pdf-module:2.5.0'
    implementation 'org.apache.cxf:cxf-rt-frontend-jaxrs:3.5.4'
    implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.74' // Remember to change the version number (9 now) in javadoc block if needed.
    implementation 'org.apache.tomcat:tomcat-jasper:9.0.74'
    implementation 'org.apache.axis2:axis2-kernel:1.8.2'
    implementation 'org.apache.xmlgraphics:batik-anim:1.14'
    implementation 'org.apache.xmlgraphics:batik-util:1.14'
    implementation 'org.apache.xmlgraphics:batik-bridge:1.14'
    implementation 'org.apache.xmlgraphics:fop:2.3' // NOTE: since 2.4 dependencies are messed up. See https://github.com/moqui/moqui-fop/blob/master/build.gradle
    implementation 'org.clojure:clojure:1.11.1'
    implementation 'org.codehaus.groovy:groovy-all:3.0.13'
    implementation 'org.freemarker:freemarker:2.3.32' // Remember to change the version number in FreeMarkerWorker class when upgrading. See OFBIZ-10019 if >= 2.4
    implementation 'org.owasp.esapi:esapi:2.5.0.0'
    implementation 'org.cyberneko:html:1.9.8'
    implementation 'org.springframework:spring-test:5.3.23'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
    implementation 'oro:oro:2.0.8'
    implementation 'wsdl4j:wsdl4j:1.6.3'
    implementation 'com.auth0:java-jwt:4.2.1'
    implementation 'org.jdom:jdom:1.1.3' // don't upgrade above 1.1.3, makes a lot of not obvious and useless complications, see last commits of OFBIZ-12092 for more
    implementation 'com.google.re2j:re2j:1.7'
    implementation 'xerces:xercesImpl:2.12.2'


    testImplementation 'org.hamcrest:hamcrest-library:2.2' // Enable junit4 to not depend on hamcrest-1.3
    testImplementation 'org.mockito:mockito-core:4.8.1'
    testImplementation 'org.jmockit:jmockit:1.49'
    testImplementation 'com.pholser:junit-quickcheck-generators:1.0'

    runtimeOnly 'javax.xml.soap:javax.xml.soap-api:1.4.0'
    runtimeOnly 'de.odysseus.juel:juel-spi:2.2.7'
    runtimeOnly 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
    runtimeOnly 'net.sf.barcode4j:barcode4j:2.1'
    runtimeOnly 'org.apache.axis2:axis2-transport-http:1.8.2'
    runtimeOnly 'org.apache.axis2:axis2-transport-local:1.8.2'
    runtimeOnly 'org.apache.derby:derby:10.14.2.0' // So far we did not update from 10.14.2.0 because of a runtime issue with 10.16.1.1: java.lang.ClassNotFoundException: org.apache.derby.jdbc.EmbeddedDriver
    runtimeOnly 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:2.1'
    runtimeOnly 'org.apache.logging.log4j:log4j-1.2-api:2.19.0' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jul:2.19.0' // for external jars using the java.util.logging: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl:2.19.0' // for external jars using slf4j: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-web:2.19.0' //???
    runtimeOnly 'org.apache.logging.log4j:log4j-jcl:2.19.0' // need to constrain to version to avoid classpath conflict (ReflectionUtil)

    // Dependencies defined by the plugins
    subprojects.each { subProject ->
        implementation project(path: subProject.path, configuration: 'pluginLibsCompile')
        runtimeOnly project(path: subProject.path, configuration: 'pluginLibsRuntime')
        compileOnly project(path: subProject.path, configuration: 'pluginLibsCompileOnly')
    }

    junitReport 'junit:junit:4.13.2'
    junitReport 'org.apache.ant:ant-junit:1.10.12'

    // Libraries downloaded manually
    implementation fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
        implementation fileTree(dir: libDir, include: '**/*.jar')
    }
    // specify last codenarc version for java 17 compliance
    codenarc('org.codenarc:CodeNarc:3.2.0')
}

def excludedJavaSources = [
    'org/apache/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java',
    'org/apache/ofbiz/accounting/thirdparty/orbital/OrbitalPaymentServices.java',
    'org/apache/ofbiz/accounting/thirdparty/paypal/PayPalServices.java',
    'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayPaymentServices.java',
    'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayServiceTest.java',
    'org/apache/ofbiz/accounting/thirdparty/verisign/PayflowPro.java',
    'org/apache/ofbiz/order/thirdparty/taxware/TaxwareException.java',
    'org/apache/ofbiz/order/thirdparty/taxware/TaxwareServices.java',
    'org/apache/ofbiz/order/thirdparty/taxware/TaxwareUTL.java'
]

sourceSets {
    main {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            exclude excludedJavaSources
        }
        groovy {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/groovy')
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/resources')
            srcDirs += getDirectoryInActiveComponentsIfExists('config')
            srcDirs += getDirectoryInActiveComponentsIfExists('dtd')
        }
    }

    test {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
        }
        groovy {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/groovy')
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/resources')
        }
    }

    groovyScripts {
        groovy {
            srcDirs += getDirectoryInActiveComponentsIfExists('groovyScripts')
            compileClasspath += sourceSets.main.compileClasspath
            compileClasspath += sourceSets.main.output
        }
    }
}

tasks.named('compileGroovyScriptsGroovy') {
    // We don't want to build groovyScripts as they should be considered as standalone elements executed in
    // isolation by ofbiz. Building them will result in numerous error due to duplicated classes.
    enabled = false
}

jar.manifest.attributes(
    'Implementation-Title': project.name,
    'Main-Class': application.mainClassName,
    'Class-Path': getJarClasspath()
)

// Checks OFBiz Java coding conventions.
checkstyle {
    // Defining a maximum number of "tolerated" errors ensures that
    // this number cannot increase in the future. It corresponds to
    // the sum of errors found last time it was changed after using the
    // 'checkstyle' tool present in the framework and in the official
    // plugins.
    tasks.checkstyleMain.maxErrors = 0
    // Currently there are no errors so we can show new one when they appear
    showViolations = true
}
gitHooks {
    hooks = ['pre-push': 'checkstyleMain']
}

// Checks OFBiz Groovy coding conventions.
codenarc {
    setConfigFile(new File('config/codenarc/codenarc.groovy'))
    setMaxPriority1Violations(0)
    setMaxPriority2Violations(448)
    setMaxPriority3Violations(4396)
}

// Eclipse plugin settings
eclipse.classpath.file.whenMerged { classpath ->
    /* The code inside this block removes unnecessary entries
     * in the .classpath file which are generated automatically
     * due to the settings in the sourceSets block
     */
    def fileSep = System.getProperty('file.separator')

    activeComponents().each { component ->
        def componentName = component.toString() - rootDir.toString() - fileSep
        def eclipseEntry = os.contains('windows') ? componentName.replaceAll("\\\\", '/') : componentName

        classpath.entries.removeAll { entry ->
            // remove any "src" entries in .classpath of the form /componentName
            entry.kind == 'src' && !(entry.path ==~ 'framework/base/config' || entry.path ==~ 'framework/base/dtd') && (
            entry.path ==~ '.*/+(' + componentName.tokenize(fileSep).last() + ')$' ||
            entry.path ==~ /(\/+framework)$/ ||
            entry.path ==~ /(\/+applications)$/ ||
            entry.path ==~ /(\/+plugins)$/ ||
            entry.path ==~ /(\/+themes)$/ ||
            entry.path ==~ eclipseEntry + '/config' ||
            entry.path ==~ eclipseEntry + '/dtd')
        }
    }
}
tasks.eclipse.dependsOn(cleanEclipse)

test {
    jvmArgs "-javaagent:${classpath.find { it.name.contains('jmockit') }.absolutePath}"
}

/* ========================================================
 * Tasks
 * ======================================================== */

// ========== Task group labels ==========
def cleanupGroup = 'Cleaning'
def docsGroup = 'Documentation'
def ofbizServer = 'OFBiz Server'
def ofbizPlugin = 'OFBiz Plugin'
def sysadminGroup = 'System Administration'

// ========== OFBiz Server tasks ==========

task loadAll(group: ofbizServer) {
    dependsOn 'ofbiz --load-data'
    description 'Load default data; meant for OFBiz development, testing, and demo purposes'
}

task testIntegration(group: ofbizServer) {
    dependsOn 'ofbiz --test'
    description 'Run OFBiz integration tests; You must run loadAll before running this task'
}

task terminateOfbiz(group: ofbizServer,
    description: 'Force termination of any running OFBiz servers, only use if \"--shutdown\" command fails') {
    doLast {
        if (os.contains('windows')) {
            Runtime.getRuntime().exec("wmic process where \"CommandLine Like \'%org.apache.ofbiz.base.start.Start%\'\" Call Terminate")
        } else {
            def processOutput = new ByteArrayOutputStream()
            exec {
                commandLine 'ps', 'ax'
                standardOutput = processOutput
            }
            processOutput.toString().split(System.lineSeparator()).each { line ->
                if (line ==~ /.*org\.apache\.ofbiz\.base\.start\.Start.*/) {
                    exec { commandLine 'kill', '-9', line.tokenize().first() }
                }
            }
        }
    }
}

task loadAdminUserLogin(group: ofbizServer) {
    description 'Create admin user with temporary password equal to ofbiz. You must provide userLoginId'
    createOfbizCommandTask('executeLoadAdminUser',
        ['--load-data', 'file=/runtime/tmp/AdminUserLoginData.xml'])
    executeLoadAdminUser.doFirst {
        copy {
            from ("${rootDir}/framework/resources/templates/AdminUserLoginData.xml") {
                filter(ReplaceTokens, tokens: [userLoginId: userLoginId])
            }
            into "${rootDir}/runtime/tmp/"
        }
    }
    dependsOn executeLoadAdminUser
    doLast {
        delete("${rootDir}/runtime/tmp/AdminUserLoginData.xml")
    }
}

task loadTenant(group: ofbizServer, description: 'Load data using tenantId') {

    createOfbizCommandTask('executeLoadTenant', [])

    if (project.hasProperty('tenantId')) {
        executeLoadTenant.args '--load-data', "delegator=default#${tenantId}"
    }
    if (project.hasProperty('tenantReaders')) {
        executeLoadTenant.args '--load-data', "readers=${tenantReaders}"
    }
    if (project.hasProperty('tenantComponent')) {
        executeLoadTenant.args '--load-data', "component=${tenantComponent}"
    }

    executeLoadTenant.doFirst {
        if (!project.hasProperty('tenantId')) {
            throw new GradleException('Missing project property tenantId')
        }
    }
    dependsOn executeLoadTenant
}

task createTenant(group: ofbizServer, description: 'Create a new tenant in your environment') {

    def databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"

    task prepareAndValidateTenantArguments {
        doLast {
            if (!project.hasProperty('tenantId')) {
                throw new GradleException('Project property tenantId is missing')
            }
            // dbPlatform values: D(Derby), M(MySQL), O(Oracle), P(PostgreSQL) (default D)
            if (project.hasProperty('dbPlatform')) {
                if (dbPlatform == 'D') {
                    databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
                } else if (dbPlatform == 'M') {
                    databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-MySQL.xml"
                } else if (dbPlatform == 'O') {
                    databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Oracle.xml"
                } else if (dbPlatform == 'P') {
                    databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml"
                } else {
                    throw new GradleException('Invalid value for property dbPlatform: ' + "${dbPlatform}")
                }
            }
        }
    }

    task generateDatabaseTemplateFile(dependsOn: prepareAndValidateTenantArguments) {
        doLast {
            def filterTokens = ['tenantId': tenantId,
                'tenantName': project.hasProperty('tenantName') ? tenantName : tenantId,
                'domainName': project.hasProperty('domainName') ? domainName : 'org.apache.ofbiz',
                'db-IP': project.hasProperty('dbIp') ? dbIp : '',
                'db-User': project.hasProperty('dbUser') ? dbUser : '',
                'db-Password': project.hasProperty('dbPassword') ? dbPassword : '']

            generateFileFromTemplate(databaseTemplateFile, 'runtime/tmp',
                filterTokens, 'tmpFilteredTenantData.xml')
        }
    }

    task generateAdminUserTemplateFile(dependsOn: prepareAndValidateTenantArguments) {
        doLast {
            generateFileFromTemplate(
                "${rootDir}/framework/resources/templates/AdminUserLoginData.xml",
                'runtime/tmp',
                ['userLoginId': "${tenantId}-admin".toString()],
                'tmpFilteredUserLogin.xml')
        }
    }

    // Load the tenants master database
    createOfbizCommandTask('loadTenantOnMasterTenantDb',
        ['--load-data', 'file=/runtime/tmp/tmpFilteredTenantData.xml',
         '--load-data', 'readers=tenant'])
    loadTenantOnMasterTenantDb.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)

    // Load the actual tenant data
    createOfbizCommandTask('loadTenantData', [])
    loadTenantData.dependsOn(loadTenantOnMasterTenantDb)

    // Load the tenant admin user account
    createOfbizCommandTask('loadTenantAdminUserLogin', [])
    loadTenantAdminUserLogin.dependsOn(loadTenantData)

    /* pass arguments to tasks, must be done this way
     * because we are in the configuration phase. We cannot
     * set the parameters at the execution phase. */
    if (project.hasProperty('tenantId')) {
        loadTenantData.args '--load-data', "delegator=default#${tenantId}"
        loadTenantAdminUserLogin.args(
            '--load-data', "delegator=default#${tenantId}",
            '--load-data', "file=${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml"
        )
    }
    if (project.hasProperty('tenantReaders')) {
        loadTenantData.args '--load-data', "readers=${tenantReaders}"
    }

    dependsOn(loadTenantAdminUserLogin)

    // cleanup
    doLast {
        delete("${rootDir}/runtime/tmp/tmpFilteredTenantData.xml")
        delete("${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml")
    }
}

// ========== Documentation tasks ==========
tasks.withType(AsciidoctorTask) { task ->
    inProcess = JAVA_EXEC
        forkOptions {
            jvmArgs("--add-opens","java.base/sun.nio.ch=ALL-UNNAMED","--add-opens","java.base/java.io=ALL-UNNAMED")
        }
    outputOptions {
         // I hate we have to do this - but JRuby (asciidoctorj-pdf) and Windows don't mix well
        if (System.properties['os.name'].toLowerCase().contains('windows')) {
            backends = ['html5']
        } else {
            backends = ['html5', 'pdf']
        }
    }
    attributes \
        'doctype': 'book',
        'revnumber': getCurrentGitBranch(),
        'experimental': '',
        'allow-uri-read': true,
        'icons': 'font',
        'sectnums': '',
        'chapter-label': '',
        'toc': 'left@',
        'toclevels': '3'
}

task deleteOfbizDocumentation {
    doFirst { delete "${buildDir}/asciidoc/ofbiz" }
}

task deletePluginDocumentation {
    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
        if(!(activeComponents().stream().anyMatch { it.name == pluginId })) {
            throw new GradleException("Could not find plugin with id ${pluginId}")
        }
        delete "${buildDir}/asciidoc/plugins/${pluginId}"
    }
}

task deleteAllPluginsDocumentation {
    doFirst { delete "${buildDir}/asciidoc/plugins" }
}


task generateReadmeFiles(group: docsGroup, type: AsciidoctorTask) {
    doFirst { delete "${buildDir}/asciidoc/readme" }
    description 'Generate OFBiz README files'
    sourceDir "${rootDir}"
    sources {
        include 'README.adoc', 'CHANGELOG.adoc', 'CONTRIBUTING.adoc'
    }
    outputDir file("${buildDir}/asciidoc/readme/")
}

task generateOfbizDocumentation(group: docsGroup, type: AsciidoctorTask) {
    dependsOn deleteOfbizDocumentation
    description 'Generate OFBiz documentation manuals'
        activeComponents().each { component ->
            copy {
                from "${component}/src/docs/asciidoc/images/${component.name}"
                include '**/*.*'
                into "${rootDir}/docs/asciidoc/images/${component.name}"
            }
        }
    sourceDir "${rootDir}/docs/asciidoc"
    outputDir file("${buildDir}/asciidoc/ofbiz")
    doLast {
        activeComponents().each { component ->
            delete "${rootDir}/docs/asciidoc/images/${component.name}"
        }
    }
}

task generatePluginDocumentation(group: docsGroup) {
    dependsOn deletePluginDocumentation
    description 'Generate plugin documentation. Expects pluginId flag'
    activeComponents()
        .findAll { project.hasProperty('pluginId') && it.name == pluginId }
        .each { component ->
            def pluginAsciidoc = task "${component.name}Documentation" (type: AsciidoctorTask) {
                def asciidocFolder = new File("${component}/src/docs/asciidoc")
                if (asciidocFolder.exists()) {
                    copy {
                        from "${rootDir}/docs/asciidoc/images/OFBiz-Logo.svg"
                        into "${component}/src/docs/asciidoc/images"
                    }
                    sourceDir file("${component}/src/docs/asciidoc")
                    outputDir file("${buildDir}/asciidoc/plugins/${component.name}")
                    doLast { println "Documentation generated for plugin ${component.name}" }
                } else {
                    println "No documentation found for plugin ${component.name}"
                }
                doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
                mustRunAfter deletePluginDocumentation
            }
            dependsOn pluginAsciidoc
            doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
        }
}

task generateAllPluginsDocumentation(group: docsGroup,
        description: 'Generate all plugins documentation.') {

    dependsOn deleteAllPluginsDocumentation
    file("${pluginsDir}").eachDir { plugin ->
        activeComponents().each { component ->
            if (component.name == plugin.name) {
                if (subprojectExists(":plugins:${plugin.name}")) {
                    // Note: the "-" between "component.name" and "Documentation" allows to differentiate from
                    // the other inner task temporary created by the generatePluginDocumentation task
                    def pluginAsciidoc = task "${component.name}-Documentation" (type: AsciidoctorTask) {
                        def asciidocFolder = new File("${component}/src/docs/asciidoc")
                        doFirst {
                            if (asciidocFolder.exists()) {
                                copy {
                                    from "${rootDir}/docs/asciidoc/images/OFBiz-Logo.svg"
                                    into "${component}/src/docs/asciidoc/images"
                                }
                            }
                        }
                        if (asciidocFolder.exists()) {
                            sourceDir file("${component}/src/docs/asciidoc")
                            outputDir file("${buildDir}/asciidoc/plugins/${component.name}")
                            doLast { println "Documentation generated for plugin ${component.name}" }
                        }
                    mustRunAfter deleteAllPluginsDocumentation
                    doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
                    }
                    dependsOn pluginAsciidoc
                }
            }
        }
    }
}


// ========== System Administration tasks ==========
task createTestReports(group: sysadminGroup, description: 'Generate HTML reports from junit XML output') {
    doLast {
        ant.taskdef(name: 'junitreport',
            classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
            classpath: configurations.junitReport.asPath)
        ant.junitreport(todir: './runtime/logs/test-results') {
            fileset(dir: './runtime/logs/test-results') {
                include(name: '*.xml')
            }
            report(format:'frames', todir:'./runtime/logs/test-results/html')
        }
    }
}

task gitInfoFooter(group: sysadminGroup, description: 'Update the Git Branch-revision info in the footer if Git is used') {
    doLast {
        def branch
        def revision
        def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
        def gitFolder = rootProject.file('.git')

        if (!gitFolder.exists()) {
            println ('Git is not used')
            return
        }

        def branchOutput = new ByteArrayOutputStream()
        exec {
            commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
            standardOutput = branchOutput
        }
        branch = branchOutput.toString()
        def revisionOutput = new ByteArrayOutputStream()
        exec {
            commandLine 'git', 'rev-parse', 'HEAD'
            standardOutput = revisionOutput
        }
        revision = revisionOutput.toString()
        gitFooterFile.delete()
        gitFooterFile.createNewFile()
        gitFooterFile <<  System.lineSeparator()
        gitFooterFile << '${uiLabelMap.CommonBranch} : ' + "${branch}" + System.lineSeparator()
        gitFooterFile << '${uiLabelMap.CommonRevision} : ' + "${revision}" + System.lineSeparator()
        gitFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
        gitFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
    }
}

// ========== OFBiz Plugin Management ==========
task createPlugin(group: ofbizPlugin, description: 'create a new plugin component based on specified templates') {
    doLast {
        if (!project.hasProperty('pluginResourceName')) {
            ext.pluginResourceName = pluginId.capitalize()
        }
        if (!project.hasProperty('webappName')) {
            ext.webappName = pluginId
        }
        if (!project.hasProperty('basePermission')) {
            ext.basePermission = pluginId.toUpperCase()
        }

        def filterTokens = ['component-name': pluginId,
            'component-resource-name': pluginResourceName,
            'webapp-name': webappName,
            'base-permission': basePermission]
        def templateDir = "${rootDir}/framework/resources/templates"
        def pluginDir = "${pluginsDir}/${pluginId}"

        ['config', 'dtd', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', 'groovyScripts', 'minilang', 'servicedef', 'src/main/java', 'src/test/java', 'testdef',
                'widget', "webapp/${webappName}/error", "webapp/${webappName}/WEB-INF"].each {
            mkdir pluginDir + '/' + it
        }

        [   [tempName:'ofbiz-component.xml', newName:'ofbiz-component.xml', location:''],
            [tempName:'build.gradle', newName:'build.gradle', location:''],
            [tempName:'TypeData.xml', newName:"${pluginResourceName}TypeData.xml", location:'data'],
            [tempName:'SecurityPermissionSeedData.xml', newName:"${pluginResourceName}SecurityPermissionSeedData.xml", location:'data'],
            [tempName:'SecurityGroupDemoData.xml', newName:"${pluginResourceName}SecurityGroupDemoData.xml", location:'data'],
            [tempName:'DemoData.xml', newName:"${pluginResourceName}DemoData.xml", location:'data'],
            [tempName:'HELP.adoc', newName:'HELP.adoc', location:''],
            [tempName:'README.adoc', newName:'README.adoc', location:''],
            [tempName:'entitymodel.xml', newName:'entitymodel.xml', location:'entitydef'],
            [tempName:'services.xml', newName:'services.xml', location:'servicedef'],
            [tempName:'Tests.xml', newName:"${pluginResourceName}Tests.xml", location:'testdef'],
            [tempName:'UiLabels.xml', newName:"${pluginResourceName}UiLabels.xml", location:'config'],
            [tempName:'index.jsp', newName:'index.jsp', location:"webapp/${webappName}"],
            [tempName:'controller.xml', newName:'controller.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'web.xml', newName:'web.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'CommonScreens.xml', newName:'CommonScreens.xml', location:'widget'],
            [tempName:'Screens.xml', newName:"${pluginResourceName}Screens.xml", location:'widget'],
            [tempName:'Menus.xml', newName:"${pluginResourceName}Menus.xml", location:'widget'],
            [tempName:'Forms.xml', newName:"${pluginResourceName}Forms.xml", location:'widget']
        ].each { tmpl ->
            generateFileFromTemplate(templateDir + '/' + tmpl.tempName,
                pluginDir + '/' + tmpl.location, filterTokens, tmpl.newName)
        }

        println "plugin successfully created in directory ${pluginsDir}/${pluginId}."
    }
}

task installPlugin(group: ofbizPlugin, description: 'executes plugin install task if it exists') {

    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
    }

    if (project.hasProperty('pluginId')) {
        activeComponents()
            .findAll { it.name == pluginId }
            .each { component ->
                if (taskExistsInproject(":plugins:${pluginId}", 'install')) {
                    dependsOn ":plugins:${pluginId}:install"
                    doLast { println "installed plugin ${pluginId}" }
                } else {
                    doLast { println "No install task defined for plugin ${pluginId}, nothing to do" }
                }
            }
    }
}

task uninstallPlugin(group: ofbizPlugin, description: 'executes plugin uninstall task if it exists') {

    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
        if (!subprojectExists(":plugins:${pluginId}")) {
            throw new GradleException("Plugin \"${pluginId}\" does not exist")
        }
    }

    if (project.hasProperty('pluginId') && taskExistsInproject(":plugins:${pluginId}", 'uninstall')) {
        dependsOn ":plugins:${pluginId}:uninstall"
        doLast { println "uninstalled plugin ${pluginId}" }
    } else {
        doLast { println "No uninstall task defined for plugin ${pluginId}" }
    }
}

task removePlugin(group: ofbizPlugin, description: 'Uninstall a plugin and delete its files') {
    if (project.hasProperty('pluginId') && subprojectExists(":plugins:${pluginId}")) {
        dependsOn uninstallPlugin
    }

    doLast {
        if (file("${pluginsDir}/${pluginId}").exists()) {
            delete "${pluginsDir}/${pluginId}"
        } else {
            throw new GradleException("Directory not found: ${pluginsDir}/${pluginId}")
        }
    }
}

task pushPlugin(group: ofbizPlugin, description: 'push an existing plugin to local maven repository') {

    if (project.hasProperty('pluginId')) {
        doFirst {
            if (!subprojectExists(":plugins:${pluginId}")) {
                throw new GradleException("Plugin ${pluginId} does not exist, cannot publish")
            }
        }
        task createPluginArchive(type: Zip) {
            from "${pluginsDir}/${pluginId}"
        }

        publishing {
            publications {
                ofbizPluginPublication(MavenPublication) {
                    artifactId pluginId
                    groupId project.hasProperty('pluginGroup') ? pluginGroup : 'org.apache.ofbiz.plugin'
                    version project.hasProperty('pluginVersion') ? pluginVersion : '0.1.0-SNAPSHOT'

                    artifact createPluginArchive

                    pom.withXml {
                        if (project.hasProperty('pluginDescription')) {
                            asNode().appendNode('description', pluginDescription)
                        } else {
                            asNode().appendNode('description', "Publication of OFBiz plugin ${pluginId}")
                        }
                    }
                }
            }
        }

        if (subprojectExists(":plugins:${pluginId}")) {
            dependsOn publishToMavenLocal
        }

    } else {
        doFirst { throw new GradleException('Missing property \"pluginId\"') }
    }
}

task pullPlugin(group: ofbizPlugin, description: 'Download and install a plugin with all dependencies') {
    doLast {
        if (!project.hasProperty('dependencyId')) {
            throw new GradleException('You must pass the dependencyId of the plugin')
        }

        // Connect to a remote maven repository if defined
        if (project.hasProperty('repoUrl')) {
            repositories {
                maven {
                    url repoUrl
                    if (project.hasProperty('repoUser') && project.hasProperty('repoPassword')) {
                        credentials {
                            username repoUser
                            password repoPassword
                        }
                    }
                }
            }
        }

        // download plugin and dependencies
        dependencies {
            ofbizPlugins dependencyId
        }

        // reverse the order of dependencies to install them before the plugin
        def ofbizPluginArchives = new ArrayList(configurations.ofbizPlugins.files)
        Collections.reverse(ofbizPluginArchives)

        // Extract and install plugin and dependencies
        ofbizPluginArchives.each { pluginArchive ->
            ext.pluginId = dependencyId.tokenize(':').get(1)
            println "installing plugin: ${pluginId}"
            copy {
                from zipTree(pluginArchive)
                into "${pluginsDir}/${pluginId}"
            }
            gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
        }
    }
}

task pullPluginSource(group: ofbizPlugin, description: 'Download and install a plugin from source control') {

    if (project.hasProperty('pluginId')) {
        // GitHub SVN feature https://docs.github.com/en/github/importing-your-projects-to-github/working-with-subversion-on-github/support-for-subversion-clients
        task pullPluginFromSvn(type: SvnCheckout) {
            def currentBranch = getCurrentGitBranch()
            // Only used for release branches
            if (currentBranch == "trunk") {
                svnUrl = "https://github.com/apache/ofbiz-plugins/trunk/${pluginId}"
            } else {
                svnUrl = "https://github.com/apache/ofbiz-plugins/branches/" + currentBranch + "/${pluginId}"
            }
            workspaceDir = "${pluginsDir}/${pluginId}"
        }
        dependsOn pullPluginFromSvn
    }
    doLast {
        gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
    }
}

task pullAllPluginsSource(group: ofbizPlugin,
        description: 'Download and install all plugins from source control. Warning! deletes existing plugins') {

    task deleteBeforePulling {
        doLast { delete "${pluginsDir}" }
    }
    task pullPluginsFromSvn(type: SvnCheckout, dependsOn: deleteBeforePulling) {
        // GitHub SVN feature https://docs.github.com/en/github/importing-your-projects-to-github/working-with-subversion-on-github/support-for-subversion-clients
        def currentBranch = getCurrentGitBranch()
        // Only used for release branches
        if (currentBranch == "trunk") {
            svnUrl = "https://github.com/apache/ofbiz-plugins/trunk"
        } else {
            svnUrl = "https://github.com/apache/ofbiz-plugins/branches/" + currentBranch
        }
        workspaceDir = "${pluginsDir}"
    }
    dependsOn pullPluginsFromSvn

    task installAllPlugins {
        subdirs(file("${pluginsDir}"))
            .filter(this.isComponentEnabled)
            .filter { taskExistsInproject(":plugins:${it.name}", 'install') }
            .forEach({ plugin ->
                dependsOn ":plugins:${plugin.name}:install"
                doLast { println "installed plugin ${plugin.name}" }
            })
    }
    doLast {
        gradlewSubprocess(['installAllPlugins'])
    }
}

// ========== Clean up tasks ==========
task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') {
    doLast { delete "${rootDir}/runtime/catalina/work" }
}
task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties']) }
}
task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') {
    doLast {
        delete fileTree(dir: "${rootDir}/framework/base/lib", includes: ['activemq-*.jar'])
        delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['postgresql-*.jar'])
        delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['mysql-*.jar'])
    }
}
task cleanLogs(group: cleanupGroup, description: 'Clean all logs in runtime/logs') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/logs/", ['README']) }
}
task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/output/", ['README']) }
}
task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/indexes/", ['README', 'index.properties']) }
}
task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') {
    doLast {
        deleteAllInDirWithExclusions("${rootDir}/runtime/tempfiles/", ['README'])
        deleteAllInDirWithExclusions("${rootDir}/runtime/tmp/", ['README'])
    }
}
task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/uploads/", []) }
}
task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') {
    doLast {
        delete fileTree(dir: "${rootDir}",
            includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
    }
}
task cleanFooterFiles(group: cleanupGroup, description: 'clean generated footer files') {
    doLast {
        delete gitFooterFile
    }
}
/*
 * Keep this task below all other clean tasks  The location of
 * declaration is important because it means that it will automatically
 * run whenever the task cleanAll executes (dependency matched by regex)
 */
def cleanTasks = tasks.findAll { it.name ==~ /^clean.+/ }
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
    description 'Execute all cleaning tasks.'
}

/* ========================================================
 * Rules-based OFBiz server commands
 * ======================================================== */

tasks.addRule('Pattern: ofbiz <Commands>: Execute OFBiz startup commands') { String taskName ->
    if (taskName ==~ /^ofbiz\s.*/ || taskName == 'ofbiz') {
        def arguments = (taskName - 'ofbiz').tokenize(' ')
        createOfbizCommandTask(taskName, arguments)
    }
}

tasks.addRule('Pattern: ofbizBackground <Commands>: Execute OFBiz startup commands in background and output to console.log') { String taskName ->
    if (taskName ==~ /^ofbizBackground\s.*/ || taskName == 'ofbizBackground') {
        createOfbizBackgroundCommandTask(taskName)
    }
}

/* ========================================================
 * Helper Functions
 * ======================================================== */

def createOfbizCommandTask(taskName, arguments) {
    task(type: JavaExec, dependsOn: classes, taskName) {
        jvmArgs(application.applicationDefaultJvmArgs)
        classpath = sourceSets.main.runtimeClasspath
        main = application.mainClassName
        args arguments
        if (taskName ==~ /^ofbiz.*(--test|-t).*/) {
            finalizedBy(createTestReports)
        }
    }
}

def createOfbizBackgroundCommandTask(taskName) {
    def sourceTask = taskName.tokenize().first()
    def arguments = (taskName - sourceTask)
    def serverCommand = "ofbiz ${arguments}".toString()

    task (taskName) {
        doLast {
            spawnProcess([gradlew, '--no-daemon', serverCommand])
        }
    }
}

def spawnProcess(command) {
    ProcessBuilder pb = new ProcessBuilder(command)
    File consoleLog = file("${rootDir}/runtime/logs/console.log")

    pb.directory(file("${rootDir}"))
    pb.redirectErrorStream(true)
    pb.redirectOutput(ProcessBuilder.Redirect.appendTo(consoleLog))
    pb.start()
}

def getDirectoryInActiveComponentsIfExists(String dirName) {
    activeComponents()
        .collect { file(it.toString() + '/' + dirName) }
        .findAll { it.exists() }
}

def deleteAllInDirWithExclusions(dirName, exclusions) {
    ant.delete (includeEmptyDirs: 'true', verbose: 'on') {
        fileset(dir: dirName, includes: '**/*', erroronmissingdir: 'false') {
            exclusions.each { exclusion ->
                exclude name: exclusion
            }
        }
    }
}

def generateFileFromTemplate(templateFileInFullPath, targetDirectory, filterTokens, newFileName) {
    copy {
        from (templateFileInFullPath) {
            filter ReplaceTokens, tokens: filterTokens
            rename templateFileInFullPath.tokenize('/').last(), newFileName
        }
        into targetDirectory
    }
}

def getJarClasspath() {
    def mapper = os.contains('windows') ? { '\\' + "$it" } : { "$it" }
    configurations.runtimeClasspath.collect(mapper).join(' ')
}

def subprojectExists(fullyQualifiedProject) {
    subprojects.stream()
        .anyMatch { it.path == fullyQualifiedProject.toString() }
}

def taskExistsInproject(fullyQualifiedProject, taskName) {
    subprojects.stream()
        .filter { it.path == fullyQualifiedProject.toString() }
        .flatMap { it.tasks.stream() }
        .anyMatch { it.name == taskName }
}

def gradlewSubprocess(commandList) {
    exec { commandLine(gradlew, '--no-daemon', *commandList) }
}


def gradle = project.getGradle()
new File("${gradle.getGradleUserHomeDir().getAbsolutePath()}/daemon/${gradle.getGradleVersion()}").listFiles().each {
    if (it.getName().endsWith('.out.log')) {
        logger.debug("Cleaning up daemon log file $it")
        it.delete()
    }
}

tasks.startScripts {
    doLast {
        // Alter the start script for Unix systems.
        unixScript.text =
                unixScript.text.replace('CLASSPATH=$APP_HOME/lib','CLASSPATH=$APP_HOME/config/:$APP_HOME/lib-extra/*:$APP_HOME/lib')
        // Alter the start script for Windows systems.
        windowsScript.text =
                windowsScript.text.replace('CLASSPATH=%APP_HOME%\\lib','CLASSPATH=%APP_HOME%\\conf\\;%APP_HOME%\\lib-extra\\*;%APP_HOME%\\lib')
    }
}
