
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import at.bxm.gradleplugins.svntools.tasks.SvnCheckout
import org.apache.tools.ant.filters.ReplaceTokens
import org.asciidoctor.gradle.AsciidoctorTask

/* ========================================================
 * Project setup
 * ======================================================== */
buildscript {
    repositories {
        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: 'java'
apply plugin: 'groovy'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: "at.bxm.svntools"
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"

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

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 = 38802
    // 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 {
            // apache-xerces:xercesImpl:2.9.1
            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()
            }
        }
        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 {
    // ofbiz compile libs
    compile 'apache-xerces:xercesImpl:2.9.1'
    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
    compile 'com.sun.mail:javax.mail:1.6.2'
    compile 'com.sun.syndication:com.springsource.com.sun.syndication:1.0.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.11.1' // the API of log4j 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.26'
    compile 'org.apache.tika:tika-parsers:1.26'
    compile 'org.apache.tomcat:tomcat-catalina-ha:9.0.54'
    compile 'org.apache.tomcat:tomcat-catalina:9.0.54'
    compile 'org.apache.tomcat:tomcat-jasper:9.0.54'
    compile 'org.apache.tomcat:tomcat-tribes:9.0.54'
    compile 'org.apache.xmlgraphics:fop:2.3'
    compile 'org.apache.xmlrpc:xmlrpc-client:3.1.3'
    compile 'org.apache.xmlrpc:xmlrpc-server:3.1.3'
    compile 'org.codehaus.groovy:groovy-all:2.4.13' // Remember to change the version number in javadoc.options block
    compile 'org.freemarker:freemarker:2.3.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 'net.lingala.zip4j:zip4j:2.6.4'
    compile 'org.apache.commons:commons-imaging:1.0-alpha2' // Alpha but OK, "Imaging was working and was used by a number of projects in production even before reaching its initial release as an Apache Commons component."
    compile 'batik:batik-svg-dom:1.6-1'

    // ofbiz unit-test compile libs
    testCompile 'org.mockito:mockito-core:2.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.11.1' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-core:2.11.1' // the implementation of the log4j 2 API
    runtime 'org.apache.logging.log4j:log4j-jul:2.11.1' // for external jars using the java.util.logging: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.1' // for external jars using slf4j: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-jcl:2.11.1' // 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 += "${rootDir}/framework/base/dtd"
            exclude excludedJavaSources
            exclude excludedConfigFiles
            // Below are necessary for unit tests run by Gradle and integration tests
            exclude { FileTreeElement elem -> elem.getName().contains('Labels.xml') }
            exclude { FileTreeElement elem -> elem.getName().contains('.properties') &&
                !elem.getName().contains('start.properties') &&
                !elem.getName().contains('load-data.properties') &&
                !elem.getName().contains('debug.properties') &&
                !elem.getName().contains('cache.properties') &&
                !elem.getName().contains('test.properties') &&
                !elem.getName().contains('rmi.properties')
            }
        }
    }

    test {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
        }
        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)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    dependsOn(loadTenantAdminUserLogin)

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

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

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

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

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


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

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

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

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

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

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

                    dependsOn pluginAsciidoc
                }
            }
        }
    }
}


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

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

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

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

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

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

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

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

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

        ['config', 'data/helpdata', 'dtd', 'documents', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', '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}"])
        }
    }
}

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

    if (project.hasProperty('pluginId')) {
        task pullPluginFromSvn(type: SvnCheckout) {
            svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release18.12/${pluginId}"
            workspaceDir = "${pluginsDir}/${pluginId}"
        }
        dependsOn pullPluginFromSvn
    }
    doLast {
        gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
    }
}

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

    task deleteBeforePulling {
        doLast { delete "${pluginsDir}" }
    }
    task pullPluginsFromSvn(type: SvnCheckout, dependsOn: deleteBeforePulling) {
        svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release18.12"
        workspaceDir = "${pluginsDir}"
    }
    dependsOn pullPluginsFromSvn

    task installAllPlugins {
        file("${pluginsDir}").eachDir { plugin ->
            iterateOverActiveComponents { component ->
                if (component.name == plugin.name) {
                    if (subprojectExists(":plugins:${plugin.name}")) {
                        if (taskExistsInproject(":plugins:${plugin.name}", 'install')) {
                            dependsOn ":plugins:${plugin.name}:install"
                            doLast { println "installed plugin ${plugin.name}" }
                        }
                    }
                }
            }
        }
    }
    doLast {
        gradlewSubprocess(['installAllPlugins'])
    }
}

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