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

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

apply from: 'common.gradle'

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

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

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

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

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

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

// root and subproject settings
defaultTasks 'build'

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

// Eclipse plugin settings
eclipse.classpath.file.whenMerged { classpath ->
    /* The code inside this block removes unnecessary entries
     * in the .classpath file which are generated automatically
     * due to the settings in the sourceSets block
     */
    def osDirSeparator = os.contains('windows') ? '\\' : '/'

    iterateOverActiveComponents { component ->
        def componentName = component.toString() - rootDir.toString() - osDirSeparator
        def eclipseEntry = os.contains('windows') ? componentName.replaceAll("\\\\", "/") : componentName

        classpath.entries.removeAll { entry ->
            // remove any "src" entries in .classpath of the form /componentName
            entry.kind == 'src' && !(entry.path ==~ 'framework/base/config' || entry.path ==~ 'framework/base/dtd') && (
            entry.path ==~ '.*/+(' + componentName.tokenize(osDirSeparator).last() + ')$' ||
            entry.path ==~ /(\/+framework)$/ ||
            entry.path ==~ /(\/+applications)$/ ||
            entry.path ==~ /(\/+plugins)$/ ||
            entry.path ==~ /(\/+themes)$/ ||
            entry.path ==~ eclipseEntry + '/config' ||
            entry.path ==~ eclipseEntry + '/dtd')
        }
    }
}
tasks.eclipse.dependsOn(cleanEclipse)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    dependsOn(loadTenantAdminUserLogin)

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

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

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

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

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


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

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

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

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

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

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

                    dependsOn pluginAsciidoc
                }
            }
        }
    }
}


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

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

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

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

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

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

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

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

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

        ['config', 'data/helpdata', 'dtd', 'documents', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', 'script', 'servicedef', 'src/main/java', 'src/test/java', 'testdef',
                'widget', "webapp/${webappName}/error", "webapp/${webappName}/WEB-INF",
                "webapp/${webappName}/WEB-INF/actions"].each {
            mkdir pluginDir+'/'+it
        }

        [   [tempName:'ofbiz-component.xml', newName:'ofbiz-component.xml', location:''],
            [tempName:'build.gradle', newName:'build.gradle', location:''],
            [tempName:'TypeData.xml', newName:"${pluginResourceName}TypeData.xml", location:'data'],
            [tempName:'SecurityPermissionSeedData.xml', newName:"${pluginResourceName}SecurityPermissionSeedData.xml", location:'data'],
            [tempName:'SecurityGroupDemoData.xml', newName:"${pluginResourceName}SecurityGroupDemoData.xml", location:'data'],
            [tempName:'DemoData.xml', newName:"${pluginResourceName}DemoData.xml", location:'data'],
            [tempName:'HELP.xml', newName:"HELP_${pluginResourceName}.xml", location:'data/helpdata'],
            [tempName:'document.xml', newName:"${pluginResourceName}.xml", location:'documents'],
            [tempName:'entitymodel.xml', newName:'entitymodel.xml', location:'entitydef'],
            [tempName:'services.xml', newName:'services.xml', location:'servicedef'],
            [tempName:'Tests.xml', newName:"${pluginResourceName}Tests.xml", location:'testdef'],
            [tempName:'UiLabels.xml', newName:"${pluginResourceName}UiLabels.xml", location:'config'],
            [tempName:'index.jsp', newName:'index.jsp', location:"webapp/${webappName}"],
            [tempName:'error.jsp', newName:'error.jsp', location:"webapp/${webappName}/error"],
            [tempName:'controller.xml', newName:'controller.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'web.xml', newName:'web.xml', location:"webapp/${webappName}/WEB-INF"],
            [tempName:'CommonScreens.xml', newName:'CommonScreens.xml', location:'widget'],
            [tempName:'Screens.xml', newName:"${pluginResourceName}Screens.xml", location:'widget'],
            [tempName:'Menus.xml', newName:"${pluginResourceName}Menus.xml", location:'widget'],
            [tempName:'Forms.xml', newName:"${pluginResourceName}Forms.xml", location:'widget']
        ].each { tmpl ->
            generateFileFromTemplate(templateDir + '/' + tmpl.tempName,
                pluginDir + '/' + tmpl.location, filterTokens, tmpl.newName)
        }

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

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

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

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

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

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

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

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

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

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

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

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

                    artifact createPluginArchive

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

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

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

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

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

        // download plugin and dependencies
        dependencies {
            ofbizPlugins dependencyId
        }

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

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

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

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

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

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

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

// ========== Clean up tasks ==========
task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') {
    doLast { delete "${rootDir}/runtime/catalina/work" }
}
task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties']) }
}
task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') {
    doLast {
        delete fileTree(dir: "${rootDir}/framework/base/lib", includes: ['activemq-*.jar'])
        delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['postgresql-*.jar'])
        delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['mysql-*.jar'])
    }
}
task cleanLogs(group: cleanupGroup, description: 'Clean all logs in runtime/logs') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/logs/", ['README']) }
}
task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/output/", ['README']) }
}
task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/indexes/", ['README', 'index.properties']) }
}
task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') {
    doLast {
        deleteAllInDirWithExclusions("${rootDir}/runtime/tempfiles/", ['README'])
        deleteAllInDirWithExclusions("${rootDir}/runtime/tmp/", ['README'])
    }
}
task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') {
    doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/uploads/", []) }
}
task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') {
    doLast {
        delete fileTree(dir: "${rootDir}",
            includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
    }
}
task cleanFooterFiles(group: cleanupGroup, description: 'clean generated footer files') {
    doLast {
        delete gitFooterFile
        delete svnFooterFile
    }
}
/*
 * Keep this task below all other clean tasks  The location of
 * declaration is important because it means that it will automatically
 * run whenever the task cleanAll executes (dependency matched by regex)
 */
def cleanTasks = getTasksMatchingRegex(/^clean.+/)
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
    description 'Execute all cleaning tasks.'
}
/*
 * With OFBIZ-11304, Checkstyle pre-push hook is installed using the
 * com.github.jakemarsden.git-hooks Gradle plugin
 * As the checkstyle plugin has some limitations
 * with Gradle 3.2 we are not able to backport.
 * See https://issues.apache.org/jira/browse/OFBIZ-11251
 * https://issues.apache.org/jira/browse/OFBIZ-11304
 * Hook once added cannot be removed when branch is
 * switched, adding dummy task to avoid push failures
 * due to absence of checkstyle plugin in R17.12
 */
task checkstyleMain {}


/* ========================================================
 * Rules-based OFBiz server commands
 * ======================================================== */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


def gradle = project.getGradle()
new File("${gradle.getGradleUserHomeDir().getAbsolutePath()}/daemon/${gradle.getGradleVersion()}").listFiles().each {
    if (it.getName().endsWith('.out.log')) {
        logger.debug("Cleaning up daemon log file $it")
        it.delete()
    }
}
