/*
 * 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 '2.2.1' // Don't update as long as we don't use Java 11, it's 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 '6.0.3' apply false
    id 'se.patrikerdes.use-latest-versions' version '0.2.15' apply false
    id 'com.github.ben-manes.versions' version '0.36.0' apply false
    id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
    id "com.github.jakemarsden.git-hooks" version "0.0.2"
}

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

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

apply from: 'common.gradle'

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

application {
    mainClassName = 'org.apache.ofbiz.base.start.Start'
    applicationDefaultJvmArgs = project.hasProperty('jvmArgs')
            ? jvmArgs.tokenize()
            : ['-Xms128M', '-Xmx1024M']
}

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.11/html/api',
            'https://commons.apache.org/proper/commons-cli/apidocs'
        )
    }
}

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

// 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 '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
            url "https://repo1.maven.org/maven2"
            metadataSources {
                artifact()
            }
        }
        maven {
            // com.springsource.com.sun.syndication
            url "https://repo.spring.io/plugins-release"
        }
    }
}

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.0'
    implementation 'com.google.zxing:core:3.4.1'
    implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
    implementation 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20200713.1'
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.15'
    implementation 'com.ibm.icu:icu4j:68.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.sun.syndication:com.springsource.com.sun.syndication:1.0.0'
    implementation 'com.thoughtworks.xstream:xstream:1.4.15'
    implementation 'commons-fileupload:commons-fileupload:1.4'
    implementation 'commons-net:commons-net:3.7.2'
    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.6.4'
    implementation 'org.apache.ant:ant-junit:1.10.9'
    implementation 'org.apache.commons:commons-collections4:4.4'
    implementation 'org.apache.commons:commons-dbcp2:2.8.0'
    implementation '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."
    implementation 'org.apache.commons:commons-text:1.9'
    implementation 'org.apache.geronimo.components:geronimo-transaction:3.1.4'
    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.14.0' // the API of log4j 2
    implementation 'org.apache.logging.log4j:log4j-core:2.14.0' // Somehow needed by Buildbot to compile OFBizDynamicThresholdFilter.java
    implementation 'org.apache.poi:poi:4.1.2'
    implementation 'org.apache.pdfbox:pdfbox:2.0.23'
    implementation 'org.apache.shiro:shiro-core:1.4.1' // So far we did not update from 1.4.1 because of a compile issue or w/ 1.7.0 an EntityCrypto exception when loading data. You may try w/ a newer version than  1.7.0
    implementation 'org.apache.sshd:sshd-core:1.7.0' // So far we did not update from 1.7.0 because of a compile issue. You may try w/ a newer version than  2.4.0
    implementation 'org.apache.tika:tika-core:1.25'
    implementation 'org.apache.tika:tika-parsers:1.25'
    implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.43' // Remember to change the version number (9 now) in javadoc block if needed.
    implementation 'org.apache.tomcat:tomcat-jasper:9.0.43'
    implementation 'org.apache.axis2:axis2-kernel:1.7.9'
    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.codehaus.groovy:groovy-all:2.5.11' // 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.2.2.0'
    implementation 'org.springframework:spring-test:5.3.2'
    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:3.11.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

    testImplementation 'org.hamcrest:hamcrest-library:2.2' // Enable junit4 to not depend on hamcrest-1.3
    testImplementation 'org.mockito:mockito-core:3.6.28'
    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.7.9'
    runtimeOnly 'org.apache.axis2:axis2-transport-local:1.7.9'
    runtimeOnly 'org.apache.derby:derby:10.14.2.0'  // So far we did not update from 10.14.2.0 because of a compile issue. You may try w/ a newer version than 10.15.1.3
    runtimeOnly 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:2.1'
    runtimeOnly 'org.apache.logging.log4j:log4j-1.2-api:2.14.0' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jul:2.14.0' // for external jars using the java.util.logging: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl:2.14.0' // for external jars using slf4j: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jcl:2.14.0' // 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.1'
    junitReport 'org.apache.ant:ant-junit:1.10.9'
    asciidoctor 'org.asciidoctor:asciidoctorj-pdf:1.5.3'
    asciidoctor 'org.jruby:jruby-complete:9.2.14.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 = 127
    // Currently there are a lot of errors so we need to temporarily
    // hide them to avoid polluting the terminal output.
    showViolations = false
}
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()}"
    }
}

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', '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')) {
        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) {
        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
        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 = 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')
    }
}
