
/*
 * 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 org.apache.tools.ant.filters.ReplaceTokens
import org.asciidoctor.gradle.AsciidoctorTask

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

apply from: 'common.gradle'

// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.pluginsDir = "${rootDir}/plugins"
ext.ofbizMainClass = 'org.apache.ofbiz.base.start.Start'

// java settings
List jvmArguments = ['-Xms128M', '-Xmx1024M', '-Djdk.serialFilter=maxarray=100000;maxdepth=20;maxrefs=1000;maxbytes=500000']
if (project.hasProperty('jvmArgs')) {
    jvmArguments = jvmArgs.tokenize()
}

application {
    mainClassName = 'org.apache.ofbiz.base.start.Start'
    // jdk.serialFilter is to "Prevent possible DOS attack done using Java deserialisation" (OFBIZ-12592)
    applicationDefaultJvmArgs = ['-Djdk.serialFilter=maxarray=100000;maxdepth=20;maxrefs=500;maxbytes=500000']
}

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

javadoc {
    title='OFBiz R18.12 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://docs.oracle.com/javaee/7/api",
            "http://docs.groovy-lang.org/docs/groovy-2.4.13/html/api",
            "https://commons.apache.org/proper/commons-cli/apidocs"
        )
    }
}
// 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 that were present before introducing the
    // ‘checkstyle’ tool present in the framework and in the official
    // plugins.
    maxErrors = 50000
    // Currently there are a lot of errors so we need to temporarily
    // hide them to avoid polluting the terminal output.
    showViolations = false
}

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 'build'

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 {
            // xerces:xercesImpl:2.12.2
            url "https://maven.repository.redhat.com/ga/"
        }
        maven {
            // net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12
            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()
            }
        }
    }
}

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

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

dependencies {
    // ofbiz compile libs
    compile 'xerces:xercesImpl:2.12.2'
    compile 'com.google.zxing:core:3.3.3'
    compile 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
    compile 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20180219.1'
    compile 'com.googlecode.libphonenumber:libphonenumber:8.9.16'
    compile 'com.ibm.icu:icu4j:63.1'
    compile('com.lowagie:itext:2.1.7') { // Don't update due to license change in newer versions, see OFBIZ-10455
        exclude module: 'bcmail-jdk14'
        exclude module: 'bcprov-jdk14'
        exclude module: 'bctsp-jdk14'
    }
    compile 'com.sun.mail:javax.mail:1.6.2'
    compile 'com.rometools:rome:1.16.0'
    compile 'com.thoughtworks.xstream:xstream:1.4.11.1'
    compile 'commons-cli:commons-cli:1.4'
    compile 'commons-net:commons-net:3.6'
    compile 'commons-validator:commons-validator:1.6'
    compile 'commons-fileupload:commons-fileupload:1.3.3'
    compile 'de.odysseus.juel:juel-impl:2.2.7'
    compile 'javax.el:javax.el-api:3.0.1-b06'
    compile 'javax.servlet:javax.servlet-api:4.0.1'
    compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'
    compile 'junit:junit-dep:4.11'
    compile 'net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12'
    compile 'org.apache.ant:ant-junit:1.10.5'
    compile 'org.apache.axis2:axis2-kernel:1.7.8'
    compile 'org.apache.commons:commons-collections4:4.2'
    compile 'org.apache.commons:commons-csv:1.6'
    compile 'org.apache.commons:commons-dbcp2:2.5.0'
    compile 'org.apache.commons:commons-text:1.6'
    compile 'org.apache.geronimo.components:geronimo-transaction:3.1.4'
    compile 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    compile 'org.apache.httpcomponents:httpclient-cache:4.5.6'
    compile 'org.apache.logging.log4j:log4j-api:2.17.2' // the API of log4j 2
    compile 'org.apache.logging.log4j:log4j-web:2.17.2' //???
    compile 'org.apache.poi:poi:3.17'
    compile 'org.apache.pdfbox:pdfbox:2.0.24'
    compile 'org.apache.shiro:shiro-core:1.4.0'
    compile 'org.apache.sshd:sshd-core:1.7.0'
    compile 'org.apache.tika:tika-core:1.28.4'
    compile 'org.apache.tika:tika-parsers:1.28.4'
    compile 'org.apache.tomcat:tomcat-catalina-ha:9.0.102'
    compile 'org.apache.tomcat:tomcat-catalina:9.0.102'
    compile 'org.apache.tomcat:tomcat-jasper:9.0.102'
    compile 'org.apache.tomcat:tomcat-tribes:9.0.102'
    compile 'org.apache.xmlgraphics:fop:2.3'
    compile 'org.codehaus.groovy:groovy-all:2.4.13' // Remember to change the version number in javadoc.options block
    compile 'org.freemarker:freemarker:2.3.31' // Remember to change the version number in FreeMarkerWorker class when upgrading
    compile 'org.hamcrest:hamcrest-all:1.3'
    compile 'org.owasp.esapi:esapi:2.1.0.1'
    compile 'org.springframework:spring-test:5.1.2.RELEASE'
    compile 'org.zapodot:jackson-databind-java-optional:2.6.1'
    compile 'oro:oro:2.0.8'
    compile 'wsdl4j:wsdl4j:1.6.3'
    compile 'org.jsoup:jsoup:1.11.3'
    compile 'com.auth0:java-jwt:3.8.2'
    compile '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
    compile 'net.lingala.zip4j:zip4j:2.6.4'
    compile 'org.apache.commons:commons-imaging:1.0-alpha2' // Alpha but OK, "Imaging was working and was used by a number of projects in production even before reaching its initial release as an Apache Commons component."
    compile 'batik:batik-svg-dom:1.6-1'
    compile 'com.google.re2j:re2j:1.6'

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

    // ofbiz runtime libs
    runtime 'javax.xml.soap:javax.xml.soap-api:1.4.0'
    runtime 'de.odysseus.juel:juel-spi:2.2.7'
    runtime 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
    runtime 'net.sf.barcode4j:barcode4j:2.1'
    runtime 'org.apache.axis2:axis2-transport-http:1.7.8'
    runtime 'org.apache.axis2:axis2-transport-local:1.7.8'
    runtime 'org.apache.derby:derby:10.14.2.0'
    runtime 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:1.1'
    runtime 'org.apache.logging.log4j:log4j-1.2-api:2.17.2' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-core:2.17.2' // the implementation of the log4j 2 API
    runtime 'org.apache.logging.log4j:log4j-jul:2.17.2' // for external jars using the java.util.logging: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.2' // for external jars using slf4j: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-jcl:2.17.2' // need to constrain to version to avoid classpath conflict (ReflectionUtil)
    runtime 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

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

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

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

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

def excludedJavaSources = [
    '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'
]

// Files and directories present in config directories that should not be included in ofbiz.jar (see OFBIZ-8321).
def excludedConfigFiles = [
    'README',
    'APACHE2_HEADER_FOR_XML',
    '*.txt',
    '*.jks',
    'fop.xconf',
    'MiniLang.xslt',
    'AutoImportTemplate.ftl',
    'axis2',
    'barcode'
]

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

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

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

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

    iterateOverActiveComponents { 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)

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

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

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

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

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

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

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

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

    createOfbizCommandTask('executeLoadTenant', [], jvmArguments, false)

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

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

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

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

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

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

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

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

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

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

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

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

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

    dependsOn(loadTenantAdminUserLogin)

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

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

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

task deletePluginDocumentation {
    def activeComponents = []
    iterateOverActiveComponents { component ->
        activeComponents.add(component.name)
    }
    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
        if(!activeComponents.contains(pluginId)) {
            throw new GradleException("Could not find plugin with id ${pluginId}")
        }
        delete "${buildDir}/asciidoc/plugins/${pluginId}"
    }
}

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


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

task generateOfbizDocumentation(group: docsGroup, type: AsciidoctorTask) {
    dependsOn deleteOfbizDocumentation
    description 'Generate OFBiz documentation manuals'
    sourceDir "${rootDir}/docs/asciidoc"
    outputDir file("${buildDir}/asciidoc/ofbiz")
}

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

                } else {
                      println "No documentation found for plugin ${component.name}"
                  }
            doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
            mustRunAfter deletePluginDocumentation
            }
            dependsOn pluginAsciidoc
            doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
        }
    }
}

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

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

                    dependsOn pluginAsciidoc
                }
            }
        }
    }
}


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

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

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

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

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

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

        exec{
            commandLine 'svn', 'info', '--xml'
            standardOutput = svnOutput
        }
        def info = new XmlParser().parseText(svnOutput.toString())
        svnFooterFile.delete()
        svnFooterFile.createNewFile()
        svnFooterFile <<  System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonBranch} : ' + "${info.entry.url.text()}" + System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonRevision} : ' + "${info.entry.commit.@revision}" + System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
        svnFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
    }
}

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

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

        ['config', 'data/helpdata', 'dtd', 'documents', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', '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.xml', newName:"HELP_${pluginResourceName}.xml", location:'data/helpdata'],
            [tempName:'document.xml', newName:"${pluginResourceName}.xml", location:'documents'],
            [tempName:'entitymodel.xml', newName:'entitymodel.xml', location:'entitydef'],
            [tempName:'services.xml', newName:'services.xml', location:'servicedef'],
            [tempName:'Tests.xml', newName:"${pluginResourceName}Tests.xml", location:'testdef'],
            [tempName:'UiLabels.xml', newName:"${pluginResourceName}UiLabels.xml", location:'config'],
            [tempName:'index.jsp', newName:'index.jsp', location:"webapp/${webappName}"],
            [tempName:'error.jsp', newName:'error.jsp', location:"webapp/${webappName}/error"],
            [tempName:'controller.xml', newName:'controller.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'web.xml', newName:'web.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'CommonScreens.xml', newName:'CommonScreens.xml', location:'widget'],
            [tempName:'Screens.xml', newName:"${pluginResourceName}Screens.xml", location:'widget'],
            [tempName:'Menus.xml', newName:"${pluginResourceName}Menus.xml", location:'widget'],
            [tempName:'Forms.xml', newName:"${pluginResourceName}Forms.xml", location:'widget']
        ].each { tmpl ->
            generateFileFromTemplate(templateDir + '/' + tmpl.tempName,
                pluginDir + '/' + tmpl.location, filterTokens, tmpl.newName)
        }

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

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

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

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

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

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

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

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

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

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

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

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

                    artifact createPluginArchive

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

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

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

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

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

        // download plugin and dependencies
        dependencies {
            ofbizPlugins dependencyId
        }

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

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

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

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

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

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

def createOfbizCommandTask(taskName, arguments, jvmArguments, isDebugMode) {

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

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

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

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

    task (taskName) {
        doLast {
            spawnProcess([gradleRunner, "--no-daemon", serverCommand])
        }
    }
}

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

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

def getDirectoryInActiveComponentsIfExists(String dirName) {
    def dirInComponents = []
    iterateOverActiveComponents { component ->
        def subDir = file(component.toString() + '/' + dirName)
        if (subDir.exists()) {
            dirInComponents.add subDir
        }
    }
    return dirInComponents
}

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

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

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


def subprojectExists(fullyQualifiedProject) {
    subprojects.stream()
        .filter { it.path == fullyQualifiedProject.toString() }
        .findAny()
        .isPresent()
}

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

def gradlewSubprocess(commandList) {
    def gradlew = os.contains('windows') ? 'gradlew.bat' : './gradlew'
    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()
    }
}
