/*
 * 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
 * ======================================================== */
plugins {
    id 'application'
    id 'groovy'
    id 'eclipse'
    id 'checkstyle'
    id 'maven-publish'
    id 'at.bxm.svntools' version '3.1' // Java 11 is needed by version 3
    id 'org.asciidoctor.convert' version '2.4.0' // About org.asciidoctor.jvm.convert as it says itself: "If you need a production-ready version of the AsciidoctorJ plugin for Gradle use a 1.5.x release of 'org.asciidoctor.convert' instead"
    id 'org.owasp.dependencycheck' version '7.1.1' 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.4.0"
}

/* 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'
    // jdk.serialFilter is to "Prevent possible DOS attack done using Java deserialisation" (OFBIZ-12592)
    applicationDefaultJvmArgs = project.hasProperty('jvmArgs')
            ? jvmArgs.tokenize()
            : ['-Xms128M','-Xmx1024M','-Djdk.serialFilter=maxarray=100000;maxdepth=20;maxrefs=500;maxbytes=500000']
}

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

javadoc {
    title='OFBiz trunk API'
    failOnError = true
    options {
        source '8'
        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/8/docs/api',
            'https://tomcat.apache.org/tomcat-9.0-doc/servletapi/',
            'http://docs.groovy-lang.org/docs/groovy-2.5.17/html/api',
            'https://commons.apache.org/proper/commons-cli/apidocs'
        )
    }
}

node {
    download = true
    version = "16.13.1"
    // npmVersion will be the one that comes default with node

    // https://github.com/node-gradle/gradle-node-plugin/blob/2.2.4/README.md
    // Set the work directory where node_modules should be located
    nodeModulesDir = file("${project.projectDir}/themes/common-theme/webapp/common-theme/js")
    // If you set a "CI" env var then ci only will be used:
    // https://github.com/node-gradle/gradle-node-plugin/blob/master/docs/faq.md#how-do-i-use-npm-ci-instead-of-npm-install
    npmInstallCommand = System.getenv("CI") ? 'ci' : 'install'
}


sourceCompatibility = '1.8'
targetCompatibility = '1.8'

// 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"
    }
    // Executes on each compilation so that if dependencies are not downloaded yet or some new dependencies are added they get automatically downloaded
    if (!project.hasProperty('skipNpmInstall')) finalizedBy 'npmInstall'
}

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

dependencies {
    implementation 'xerces:xercesImpl:2.12.2'
    implementation 'com.google.zxing:core:3.5.0'
    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.50'
    implementation 'com.ibm.icu:icu4j:71.1'
    implementation 'com.lowagie:itext:2.1.7' // Don't update due to license change in newer versions, see OFBIZ-10455
    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-fileupload:commons-fileupload:1.4'
    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 'net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12'
    implementation 'net.lingala.zip4j:zip4j:2.11.1'
    implementation 'org.apache.ant:ant-junit:1.10.12'
    implementation 'org.apache.commons:commons-collections4:4.4'
    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.9'
    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.17.2' // the API of log4j 2
    implementation 'org.apache.logging.log4j:log4j-core:2.17.2' // 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.24'
    implementation 'org.apache.shiro:shiro-core:1.9.0'
    implementation 'org.apache.sshd:sshd-core:2.8.0'
    implementation 'org.apache.sshd:sshd-sftp:2.8.0'
    // Note: The Apache Tika PMC has set September 30, 2022 as the End Of Life for the Tika 1.x branch.
    //       The PMC will make security fixes for the 1.x branch until that date.
    implementation 'org.apache.tika:tika-core:1.28.4'
    implementation 'org.apache.tika:tika-parsers:1.28.4' //  2.4.1 does not work,
    implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.60' // Remember to change the version number (9 now) in javadoc block if needed.
    implementation 'org.apache.tomcat:tomcat-jasper:9.0.60'
    implementation 'org.apache.axis2:axis2-kernel:1.8.1'
    implementation 'batik:batik-svg-dom:1.6-1'
    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.apache.xmlrpc:xmlrpc-client:3.1.3'
    implementation 'org.apache.xmlrpc:xmlrpc-server:3.1.3'
    implementation 'org.clojure:clojure:1.11.1'
    implementation 'org.codehaus.groovy:groovy-all:2.5.17' // Compile issue with commons-cli and Groovy 3. Remember to change the version number in javadoc block.
    implementation 'org.freemarker:freemarker:2.3.31' // Remember to change the version number in FreeMarkerWorker class when upgrading. See OFBIZ-10019 if >= 2.4
    implementation 'org.owasp.esapi:esapi:2.4.0.0'
    implementation 'org.cyberneko:html:1.9.8'
    implementation 'org.springframework:spring-test:5.3.21'
    implementation 'org.zapodot:jackson-databind-java-optional:2.6.1'
    implementation 'oro:oro:2.0.8'
    implementation 'wsdl4j:wsdl4j:1.6.3'
    implementation 'com.auth0:java-jwt:4.0.0'
    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.6'

    testImplementation 'org.hamcrest:hamcrest-library:2.2' // Enable junit4 to not depend on hamcrest-1.3
    testImplementation 'org.mockito:mockito-core:4.6.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.1'
    runtimeOnly 'org.apache.axis2:axis2-transport-local:1.8.1'
    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.17.2' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jul:2.17.2' // for external jars using the java.util.logging: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2' // for external jars using slf4j: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-web:2.17.2' //???
    runtimeOnly 'org.apache.logging.log4j:log4j-jcl:2.17.2' // need to constrain to version to avoid classpath conflict (ReflectionUtil)
    runtimeOnly 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

    // 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'
    asciidoctor 'org.asciidoctor:asciidoctorj-pdf:1.5.3'
    asciidoctor 'org.jruby:jruby-complete:9.2.19.0' // bug workaround - see OFBIZ-9873

    // Libraries downloaded manually
    implementation fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
        implementation fileTree(dir: libDir, include: '**/*.jar')
    }
}

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

// 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 ->
    backends 'html5', 'pdf'
    attributes \
        'doctype': 'book',
        'revnumber': 'Trunk',
        '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().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'
        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 = 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()}"
    }
}

// ========== 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) {
            svnUrl = "https://github.com/apache/ofbiz-plugins/trunk/${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
        svnUrl = "https://github.com/apache/ofbiz-plugins/trunk"
        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
    }
}
task cleanNpm(group: cleanupGroup, description: 'clean node modules') {
    doLast {
        delete "${project.projectDir}/themes/common-theme/webapp/common-theme/js/node_modules"
    }
}
/*
 * 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')
    }
}
