/*
 * 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.AsciidoctorTask

/* ========================================================
 * Project setup
 * ======================================================== */
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'at.bxm.gradleplugins:gradle-svntools-plugin:2.2.1'
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.8.1' // Rather than using 1.5.9.2 see OFBIZ-10693
        classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16'
    }
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: "at.bxm.svntools"
apply plugin: 'org.asciidoctor.convert'

apply from: 'common.gradle'

// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.pluginsDir = "${rootDir}/plugins"

// java settings
List jvmArguments = ['-Xms128M', '-Xmx1024M']
if (project.hasProperty('jvmArgs')) {
    jvmArguments = jvmArgs.tokenize()
}
ext.ofbizMainClass = 'org.apache.ofbiz.base.start.Start'

javadoc.failOnError = true
javadoc.title = "OFBiz R17.12 API"
javadoc.options {
    encoding "UTF-8"
    charSet "UTF-8"
}

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

// Java compile options, syntax gradlew -PXlint build
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    if (project.hasProperty('Xlint')) {
        options.compilerArgs << "-Xlint"
    }
}

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

// root and subproject settings
defaultTasks 'build'

allprojects {
    repositories{
        jcenter()
        mavenLocal()
    }
}

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

dependencies {
    // ofbiz compile libs
    compile 'apache-xerces:xercesImpl:2.9.1'
    compile 'com.google.zxing:core:3.3.1'
    compile 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
    compile 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20170515.1'
    compile 'com.googlecode.libphonenumber:libphonenumber:8.9.16'
    compile 'com.ibm.icu:icu4j:60.2'
    compile 'com.lowagie:itext:2.1.7' // Don't update due to license change in newer versions, see OFBIZ-10455
    compile 'com.sun.mail:javax.mail:1.6.0'
    compile 'com.sun.syndication:com.springsource.com.sun.syndication:0.9.0'
    compile 'com.thoughtworks.xstream:xstream:1.4.10'
    compile 'commons-cli:commons-cli:1.4'
    compile 'commons-net:commons-net:3.6'
    compile 'commons-validator:commons-validator:1.6'
    compile 'commons-fileupload:commons-fileupload:1.3.3'
    compile 'de.odysseus.juel:juel-impl:2.2.7'
    compile 'javax.el:javax.el-api:3.0.1-b04'
    compile 'javax.servlet:javax.servlet-api:4.0.0'
    compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02'
    compile 'junit:junit-dep:4.11'
    compile 'net.fortuna.ical4j:ical4j:1.0-rc3-atlassian-11'
    compile 'org.apache.ant:ant-junit:1.10.1'
    compile 'org.apache.axis2:axis2-kernel:1.7.7'
    compile 'org.apache.commons:commons-collections4:4.1'
    compile 'org.apache.commons:commons-csv:1.5'
    compile 'org.apache.commons:commons-dbcp2:2.1.1'
    compile 'org.apache.commons:commons-text:1.6'
    compile 'org.apache.geronimo.components:geronimo-transaction:3.1.4'
    compile 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    compile 'org.apache.httpcomponents:httpclient-cache:4.5.4'
    compile 'org.apache.logging.log4j:log4j-api:2.10.0' // the API of log4j 2
    compile 'org.apache.shiro:shiro-core:1.4.0'
    compile 'org.apache.tika:tika-core:1.24.1'
    compile 'org.apache.tika:tika-parsers:1.24.1'
    compile 'org.apache.poi:poi:3.17'
    compile 'org.apache.tomcat:tomcat-catalina-ha:9.0.36'
    compile 'org.apache.tomcat:tomcat-catalina:9.0.36'
    compile 'org.apache.tomcat:tomcat-jasper:9.0.36'
    compile 'org.apache.tomcat:tomcat-tribes:9.0.36'
    compile 'org.apache.xmlgraphics:fop:2.2'
    compile 'org.apache.xmlrpc:xmlrpc-client:3.1.3'
    compile 'org.apache.xmlrpc:xmlrpc-server:3.1.3'
    compile 'org.codehaus.groovy:groovy-all:2.4.13' // Remember to change the version number in javadoc.options block
    compile 'org.freemarker:freemarker:2.3.28' // Remember to change the version number in FreeMarkerWorker class when upgrading
    compile 'org.hamcrest:hamcrest-all:1.3'
    compile 'org.owasp.esapi:esapi:2.1.0.1'
    compile 'org.springframework:spring-test:5.0.2.RELEASE'
    compile 'org.zapodot:jackson-databind-java-optional:2.6.1'
    compile 'oro:oro:2.0.8'
    compile 'wsdl4j:wsdl4j:1.6.3'
    compile 'org.jsoup:jsoup:1.11.2'
    compile 'net.lingala.zip4j:zip4j:2.6.4'
    compile 'org.apache.commons:commons-imaging:1.0-alpha2' // 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."
    compile 'batik:batik-svg-dom:1.6-1'

    // ofbiz unit-test compile libs
    testCompile 'org.mockito:mockito-core:2.+'

    // ofbiz runtime libs
    runtime 'de.odysseus.juel:juel-spi:2.2.7'
    runtime 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
    runtime 'net.sf.barcode4j:barcode4j:2.1'
    runtime 'org.apache.axis2:axis2-transport-http:1.7.7'
    runtime 'org.apache.axis2:axis2-transport-local:1.7.7'
    runtime 'org.apache.derby:derby:10.14.1.0'
    runtime 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:1.1'
    runtime 'org.apache.logging.log4j:log4j-1.2-api:2.10.0' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-core:2.10.0' // the implementation of the log4j 2 API
    runtime 'org.apache.logging.log4j:log4j-jul:2.10.0' // for external jars using the java.util.logging: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.10.0' // for external jars using slf4j: routes logging to log4j 2
    runtime 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

    // plugin libs
    subprojects.each { subProject ->
        compile project(path: subProject.path, configuration: 'pluginLibsCompile')
        runtime project(path: subProject.path, configuration: 'pluginLibsRuntime')
        compileOnly project(path: subProject.path, configuration: 'pluginLibsCompileOnly')
    }

    // libs needed for junitreport
    junitReport 'junit:junit:4.12'
    junitReport 'org.apache.ant:ant-junit:1.9.7'

    // bug workaround - see OFBIZ-9873
    asciidoctor 'org.jruby:jruby-complete:9.2.4.0'

    // local libs
    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
        compile fileTree(dir: libDir, include: '**/*.jar')
    }
    compile fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
}

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


// These files and directories present in config directories should not be included in ofbiz.jar see OFBIZ-8321
def excludedConfigFiles = []
excludedConfigFiles.add 'README'
excludedConfigFiles.add 'APACHE2_HEADER_FOR_XML'
excludedConfigFiles.add '*.txt'
excludedConfigFiles.add '*.jks'
excludedConfigFiles.add 'fop.xconf'
excludedConfigFiles.add 'GroovyInit.groovy'
excludedConfigFiles.add 'MiniLang.xslt'
excludedConfigFiles.add 'AutoImportTemplate.ftl'
excludedConfigFiles.add 'axis2'
excludedConfigFiles.add 'barcode'


sourceSets {
    main {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            exclude excludedJavaSources
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            srcDirs += getDirectoryInActiveComponentsIfExists('config')
            srcDirs += "${rootDir}/framework/base/dtd"
            exclude excludedJavaSources
            exclude excludedConfigFiles
            // Below are necessary for unit tests run by Gradle and integration tests
            exclude { FileTreeElement elem -> elem.getName().contains('Labels.xml') }
            exclude { FileTreeElement elem -> elem.getName().contains('.properties') &&
                !elem.getName().contains('start.properties') &&
                !elem.getName().contains('load-data.properties') &&
                !elem.getName().contains('debug.properties') &&
                !elem.getName().contains('cache.properties') &&
                !elem.getName().contains('test.properties') &&
                !elem.getName().contains('rmi.properties')
            }
        }
    }

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

jar {
    manifest {
        attributes(
            "Implementation-Title": project.name,
            "Main-Class": ofbizMainClass,
            "Class-Path": getJarManifestClasspathForCurrentOs()
        )
    }
}

// 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 osDirSeparator = os.contains('windows') ? '\\' : '/'

    iterateOverActiveComponents { component ->
        def componentName = component.toString() - rootDir.toString() - osDirSeparator
        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(osDirSeparator).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)

/* 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
 */
buildscript {
    if (project.hasProperty('enableOwasp')) {
        repositories {
            maven {
                url "https://plugins.gradle.org/m2/"
            }
        }
        dependencies {
            classpath 'org.owasp:dependency-check-gradle:3.0.2'
        }
    }
}
if (project.hasProperty('enableOwasp')) {
    apply plugin: 'org.owasp.dependencycheck'
}

/* ========================================================
 * 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'],
        jvmArguments, false)
    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', [], jvmArguments, false)

    if (project.hasProperty('tenantId')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "delegator=default#${tenantId}"
    }
    if (project.hasProperty('tenantReaders')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "readers=${tenantReaders}"
    }
    if (project.hasProperty('tenantComponent')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "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'],
        jvmArguments, false)
    loadTenantOnMasterTenantDb.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)

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

    // Load the tenant admin user account
    createOfbizCommandTask('loadTenantAdminUserLogin', [], jvmArguments, false)
    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'
        loadTenantData.args "delegator=default#${tenantId}"

        loadTenantAdminUserLogin.args '--load-data'
        loadTenantAdminUserLogin.args "delegator=default#${tenantId}"
        loadTenantAdminUserLogin.args '--load-data'
        loadTenantAdminUserLogin.args "file=${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml"
    }
    if (project.hasProperty('tenantReaders')) {
        loadTenantData.args '--load-data'
        loadTenantData.args "readers=${tenantReaders}"
    }

    dependsOn(loadTenantAdminUserLogin)

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

// ========== Documentation tasks ==========
tasks.withType(AsciidoctorTask) { task ->
    backends 'html5', 'pdf'
    attributes \
        'doctype': 'book',
        'experimental': '',
        'icons': 'font',
        'sectnums': '',
        'chapter-label': '',
        'toc': 'left@',
        'toclevels': '3'
}

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

task deletePluginDocumentation {
    def activeComponents = []
    iterateOverActiveComponents { component ->
        activeComponents.add(component.name)
    }
    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
        if(!activeComponents.contains(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'
    sourceDir "${rootDir}/docs/asciidoc"
    outputDir file("${buildDir}/asciidoc/ofbiz")
}

task generatePluginDocumentation(group: docsGroup) {
    dependsOn deletePluginDocumentation
    description 'Generate plugin documentation. Expects pluginId flag'
    iterateOverActiveComponents { component ->
        if (project.hasProperty('pluginId') && component.name == pluginId) {
            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 ->
        iterateOverActiveComponents { 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 = new 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()}"
    }
}

task svnInfoFooter(group: sysadminGroup, description: 'Update the Subversion revision info in the footer if Subversion is used') {
    doLast {
        def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
        def svnOutput = new ByteArrayOutputStream()
        def svnFolder = new File('.svn')

        if (!svnFolder.exists()) {
          println ("Subversion is not used")
          return
        }

        exec{
            commandLine 'svn', 'info', '--xml'
            standardOutput = svnOutput
        }
        def info = new XmlParser().parseText(svnOutput.toString())
        svnFooterFile.delete()
        svnFooterFile.createNewFile()
        svnFooterFile <<  System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonBranch} : ' + "${info.entry.url.text()}" + System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonRevision} : ' + "${info.entry.commit.@revision}" + System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
        svnFooterFile << '${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', 'data/helpdata', 'dtd', 'documents', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', 'script', 'servicedef', 'src/main/java', 'src/test/java', 'testdef',
                'widget', "webapp/${webappName}/error", "webapp/${webappName}/WEB-INF",
                "webapp/${webappName}/WEB-INF/actions"].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.xml', newName:"HELP_${pluginResourceName}.xml", location:'data/helpdata'],
            [tempName:'document.xml', newName:"${pluginResourceName}.xml", location:'documents'],
            [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:'error.jsp', newName:'error.jsp', location:"webapp/${webappName}/error"],
            [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')) {
        iterateOverActiveComponents { component ->
            if (component.name == pluginId) {
                if (subprojectExists(":plugins:${pluginId}")) {
                    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')) {
        task pullPluginFromSvn(type: SvnCheckout) {
            svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release17.12/${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) {
        svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release17.12"
        workspaceDir = "${pluginsDir}"
    }
    dependsOn pullPluginsFromSvn

    task installAllPlugins {
        file("${pluginsDir}").eachDir { plugin ->
            iterateOverActiveComponents { component ->
                if (component.name == plugin.name) {
                    if (subprojectExists(":plugins:${plugin.name}")) {
                        if (taskExistsInproject(":plugins:${plugin.name}", 'install')) {
                            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
        delete svnFooterFile
    }
}
/*
 * 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 = getTasksMatchingRegex(/^clean.+/)
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
    description 'Execute all cleaning tasks.'
}
/*
 * With OFBIZ-11304, Checkstyle pre-push hook is installed using the
 * com.github.jakemarsden.git-hooks Gradle plugin
 * As the checkstyle plugin has some limitations
 * with Gradle 3.2 we are not able to backport.
 * See https://issues.apache.org/jira/browse/OFBIZ-11251
 * https://issues.apache.org/jira/browse/OFBIZ-11304
 * Hook once added cannot be removed when branch is
 * switched, adding dummy task to avoid push failures
 * due to absence of checkstyle plugin in R17.12
 */
task checkstyleMain {}


/* ========================================================
 * 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, jvmArguments, false)
    }
}

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

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, jvmArguments, isDebugMode) {

    def ofbizJarName = buildDir.toString()+'/libs/'+project.name+'.jar'

    task(type: JavaExec, dependsOn: build, taskName) {
        jvmArgs(jvmArguments)
        debug = isDebugMode
        classpath = files(ofbizJarName)
        main = ofbizMainClass
        arguments.each { argument ->
            args argument
        }

        if (taskName ==~ /^ofbiz.*--test.*/
            || taskName ==~ /^ofbiz.*-t.*/) {
            finalizedBy(createTestReports)
        }
    }
}

def createOfbizBackgroundCommandTask(taskName) {
    def sourceTask = taskName.tokenize().first()
    def arguments = (taskName - sourceTask)
    def serverCommand = "ofbiz ${arguments}".toString()
    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'

    task (taskName) {
        doLast {
            spawnProcess([gradleRunner, "--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) {
    def dirInComponents = []
    iterateOverActiveComponents { component ->
        def subDir = file(component.toString() + '/' + dirName)
        if (subDir.exists()) {
            dirInComponents.add subDir
        }
    }
    return dirInComponents
}

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

def getTasksMatchingRegex(theRegex) {
    def filteredTasks = []
    tasks.each { task ->
        if (task.name ==~ theRegex) {
            filteredTasks.add(task)
        }
    }
    return filteredTasks
}

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

def getJarManifestClasspathForCurrentOs() {
    def osClassPath = ''
    if (os.contains('windows')) {
        configurations.runtime.files.each { cpEntry ->
            osClassPath += '\\' + cpEntry.toString() + ' '
        }
    } else {
        osClassPath = configurations.runtime.files.collect { "$it" }.join(' ')
    }
    return osClassPath
}

def subprojectExists(fullyQualifiedProject) {
    def projectFound = false
    subprojects.each { subproject ->
        if (subproject.getPath().equals(fullyQualifiedProject.toString())) {
            projectFound = true
        }
    }
    return projectFound
}

def taskExistsInproject(fullyQualifiedProject, taskName) {
    def taskExists = false
    subprojects.each { subProject ->
        if (subProject.getPath().equals(fullyQualifiedProject.toString())) {
            subProject.tasks.each { projTask ->
                if (taskName.equals(projTask.name)) {
                    taskExists = true
                }
            }
        }
    }
    return taskExists
}

def gradlewSubprocess(commandList) {
    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'
    def fullCommand = [gradleRunner, "--no-daemon"]
    fullCommand.addAll(commandList)
    exec { commandLine fullCommand }
}


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