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

/* ========================================================
 * Project setup
 * ======================================================== */

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

apply from: 'common.gradle'

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

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

// Java compile options
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
    }
}

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.2.1'
    compile 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.0'
    compile 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20160628.1'
    compile 'com.ibm.icu:icu4j:57.1'
    compile 'com.lowagie:itext:2.1.7'
    compile 'com.sun.mail:javax.mail:1.5.1'
    compile 'com.sun.syndication:com.springsource.com.sun.syndication:0.9.0'
    compile 'com.thoughtworks.xstream:xstream:1.4.9'
    compile 'commons-cli:commons-cli:1.3.1'
    compile 'commons-net:commons-net:3.3'
    compile 'commons-validator:commons-validator:1.5.1'
    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:3.1.0'
    compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.0'
    compile 'junit:junit-dep:4.10'
    compile 'net.fortuna.ical4j:ical4j:1.0-rc3-atlassian-11'
    compile 'org.apache.ant:ant-junit:1.9.0'
    compile 'org.apache.axis2:axis2-kernel:1.7.1'
    compile 'org.apache.commons:commons-collections4:4.1'
    compile 'org.apache.commons:commons-csv:1.1'
    compile 'org.apache.commons:commons-dbcp2:2.1'
    compile 'org.apache.geronimo.components:geronimo-transaction:3.1.1'
    compile 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    compile 'org.apache.httpcomponents:httpclient-cache:4.4.1'
    compile 'org.apache.logging.log4j:log4j-api:2.6.2' // the API of log4j 2
    compile 'org.apache.poi:poi:3.14'
    compile 'org.apache.shiro:shiro-core:1.3.0'
    compile 'org.apache.tika:tika-core:1.12'
    compile 'org.apache.tika:tika-parsers:1.12'
    compile 'org.apache.tomcat:tomcat-catalina-ha:8.0.42'
    compile 'org.apache.tomcat:tomcat-catalina:8.0.42'
    compile 'org.apache.tomcat:tomcat-jasper:8.0.42'
    compile 'org.apache.tomcat:tomcat-tribes:8.0.42'
    compile 'org.apache.xmlgraphics:fop:2.1'
    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.5'
    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'
    compile 'org.springframework:spring-test:4.2.3.RELEASE'
    compile 'org.zapodot:jackson-databind-java-optional:2.4.2'
    compile 'oro:oro:2.0.8'
    compile 'wsdl4j:wsdl4j:1.6.2'
    compile 'org.jsoup:jsoup:1.11.2'

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

    // 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.1'
    runtime 'org.apache.axis2:axis2-transport-local:1.7.1'
    runtime 'org.apache.derby:derby:10.11.1.1'
    runtime 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:1.1'
    runtime 'org.apache.logging.log4j:log4j-1.2-api:2.6.2' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-core:2.6.2' // the implementation of the log4j 2 API
    runtime 'org.apache.logging.log4j:log4j-jul:2.6.2' // for external jars using the java.util.logging: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.6.2' // for external jars using slf4j: routes logging to log4j 2
    runtime 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

    /* TODO We suspect that all the below dependencies are not needed and can be
     * deleted from this file. They used to be compile time dependencies and we
     * converted them to runtime and OFBiz seems to operate normally without them.
     * We are keeping them until thorough testing is done to ensure correct
     * operation without these libraries.
     */
    runtime 'apache-xerces:resolver:2.9.1'
    runtime 'commons-el:commons-el:1.0'
    runtime 'net.sf.dozer:dozer:4.2.1'
    runtime 'org.apache.axis2:axis2-adb:1.7.1'
    runtime 'org.apache.httpcomponents:httpcore:4.4.1'
    runtime 'org.apache.servicemix.bundles:org.apache.servicemix.bundles.xpp3:1.1.4c_7'
    runtime 'org.apache.tomcat.extras:tomcat-extras-juli-adapters:8.0.42'
    runtime 'org.apache.xalan:com.springsource.org.apache.xml.serializer:2.7.1'
    runtime 'ws-commons-java5:ws-commons-java5:1.0.1'

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

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

    // 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')
            exclude excludedJavaSources
            exclude excludedConfigFiles
            // Below are necessary for unit tests run by Gradle and integration tests
            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')}
            exclude { FileTreeElement elem -> elem.getName().contains('.xml') && 
                !elem.getName().contains('entityengine.xml')
                }
        }
    }

    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 ==~ '.*/+(' + componentName.tokenize(osDirSeparator).last() + ')$' ||
            entry.path ==~ /(\/+framework)$/ ||
            entry.path ==~ /(\/+applications)$/ ||
            entry.path ==~ /(\/+specialpurpose)$/ ||
            entry.path ==~ /(\/+themes)$/ ||
            entry.path ==~ /(\/+hot-deploy)$/ ||
            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 dependencyCheck
 */
buildscript {
    if (project.hasProperty('enableOwasp')) {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'org.owasp:dependency-check-gradle:1.4.0'
        }
    }
}
if (project.hasProperty('enableOwasp')) {
    apply plugin: 'org.owasp.dependencycheck'
}

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

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

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

task loadDefault(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 loadDefault before running this task'
}

task terminateOfbiz(group: ofbizServer,
    description: 'Force termination of any running OFBiz servers, only use if \"--shutdown\" command fails') << {
    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 << {
        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) << {
        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) << {
        generateFileFromTemplate(
            "${rootDir}/framework/resources/templates/AdminUserLoginData.xml",
            'runtime/tmp',
            ['userLoginId': "${tenantId}-admin".toString()],
            'tmpFilteredUserLogin.xml')
    }

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

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

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

// ========== System Administration tasks ==========
task createTestReports(group: sysadminGroup, description: 'Generate HTML reports from junit XML output') << {
    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')
    }
}
/*
 * TODO replace this code with something more declarative.
 * We are using it so that if tests fail we still get HTML reports
 */
gradle.taskGraph.afterTask { Task task, TaskState state ->
    if (task.name ==~ /^ofbiz.*--test.*/
        || task.name ==~ /^ofbiz.*-t.*/) {
        tasks.createTestReports.execute()
    }
}

// ========== OFBiz Plugin Management ==========
task createPlugin(group: ofbizPlugin, description: 'create a new plugin component based on specified templates') << {
    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}"

    mkdir pluginDir
    mkdir pluginDir+"/config"
    mkdir pluginDir+"/data"
    mkdir pluginDir+"/data/helpdata"
    mkdir pluginDir+"/dtd"
    mkdir pluginDir+"/documents"
    mkdir pluginDir+"/entitydef"
    mkdir pluginDir+"/lib"
    mkdir pluginDir+"/patches"
    mkdir pluginDir+"/patches/test"
    mkdir pluginDir+"/patches/qa"
    mkdir pluginDir+"/patches/production"
    mkdir pluginDir+"/script"
    mkdir pluginDir+"/servicedef"
    mkdir pluginDir+"/src"
    mkdir pluginDir+"/testdef"
    mkdir pluginDir+"/webapp"
    mkdir pluginDir+"/webapp/${webappName}"
    mkdir pluginDir+"/webapp/${webappName}/error"
    mkdir pluginDir+"/webapp/${webappName}/WEB-INF"
    mkdir pluginDir+"/webapp/${webappName}/WEB-INF/actions"
    mkdir pluginDir+"/widget/"

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

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

task installPlugin(group: ofbizPlugin, description: 'activate a plugin and run its install task if it exists') {

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

    if (project.hasProperty('pluginId')) {
        if (subprojectExists(":specialpurpose:${pluginId}")) {
            if (taskExistsInproject(":specialpurpose:${pluginId}", 'install')) {
                dependsOn ":specialpurpose:${pluginId}:install"
                doLast { println "installed plugin ${pluginId}" }
            } else {
                doLast { println "No install task defined for plugin ${pluginId}" }
            }
        } else {
            /* if the plugin is not added to component-load.xml, then add
             * it to the file and call gradle again to load the new plugin
             * as a gradle subproject and install it i.e. gradle calling gradle
             */
            doLast {
                activateAndInstallPlugin pluginId
            }
        }
    }
}

task uninstallPlugin(group: ofbizPlugin, description: 'run the uninstall task if exists for a plugin and deactivate it') {

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

    if (project.hasProperty('pluginId') && taskExistsInproject(":specialpurpose:${pluginId}", 'uninstall')) {
        dependsOn ":specialpurpose:${pluginId}:uninstall"
    }

    doLast {
        deactivatePlugin pluginId
    }
}

task removePlugin(group: ofbizPlugin, description: 'Uninstall a plugin and delete its files') {
    if (project.hasProperty('pluginId') && subprojectExists(":specialpurpose:${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(":specialpurpose:${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(":specialpurpose:${pluginId}")) {
            dependsOn publishToMavenLocal
        }

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

task pullPlugin(group: ofbizPlugin, description: 'Download and install a plugin with all dependencies') << {
    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}"
        }
        activateAndInstallPlugin pluginId
    }
}

// ========== Clean up tasks ==========
task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') << {
    delete "${rootDir}/runtime/catalina/work"
}
task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties'])
}
task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') << {
    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') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/logs/", ['README'])
}
task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/output/", ['README'])
}
task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/indexes/", ['README', 'index.properties'])
}
task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/tempfiles/", ['README'])
    deleteAllInDirWithExclusions("${rootDir}/runtime/tmp/", ['README'])
}
task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/uploads/", [])
}
task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') << {
    delete fileTree(dir: "${rootDir}", includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
}
task cleanGradle(group: cleanupGroup, description: 'clean generated files from Gradle') << {
    delete file("${rootDir}/.gradle")
}
task cleanFooterFiles(group: cleanupGroup, description: 'clean generated footer files') << {
    delete gitFooterFile
    delete svnFooterFile
}
task cleanAnt(group: cleanupGroup, type: Delete, description: "clean old artifacts generated by Ant") << {
    /* TODO this task is temporary and should be deleted after some
     * time when users have updated their trees. */
    ['framework', 'specialpurpose', 'applications'].each { componentGroup ->
        file(componentGroup).eachDir { component ->
            delete file(component.toString() + '/build')
        }
    }
    delete 'ofbiz.jar'
}

/*
 * 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.'
}

// ========== Tasks for OFBiz committers ==========
def websiteDir = "${rootDir}/../site"
task copyDtds(group: committerGroup, description: 'Copy all DTDs from OFBiz instance to website') << {
    mkdir websiteDir+'/dtds'
    copy {
        from (fileTree("${rootDir}").files) {
            include '**/*.xsd'
            exclude '**/002*.xsd'
            exclude '**/068*.xsd'
            exclude '**/161*.xsd'
            exclude '**/196*.xsd'
            exclude '**/197*.xsd'
        }
        into websiteDir+'/dtds'
    }
}

task gitInfoFooter(group: committerGroup, description: 'Update the Git Branch-revision info in the footer if Git is used') << {
    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 << '${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: committerGroup, description: 'Update the Subversion revision info in the footer if Subversion is used') << {
    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 << '${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()}"
}

/* ========================================================
 * 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').toLowerCase().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').toLowerCase().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
        }

    }
}

def createOfbizBackgroundCommandTask(taskName) {
    def sourceTask = taskName.tokenize().first()
    def arguments = (taskName - sourceTask)

    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'

    task (taskName) {
        doLast {
            spawnProcess(gradleRunner, "ofbiz ${arguments}")
        }
    }
}

def spawnProcess(command, arguments) {
    ProcessBuilder pb = new ProcessBuilder(command, arguments)
    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 componentExistsInRegister(componentRegister, componentName) {
    def componentFound = false
    componentRegister.children().each { component ->
        if (componentName.equals(component.@"component-location")) {
            componentFound = true
        }
    }
    return componentFound
}

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 activatePlugin(pluginId) {
    def pluginLoadFile = "${pluginsDir}/component-load.xml"
    def componentRegister = new XmlParser().parse(pluginLoadFile)

    // check that plugin directory exists.
    if (!file("${pluginsDir}/${pluginId}").exists()) {
        throw new GradleException("Cannot add plugin \"${pluginId}\", directory does not exist")
    }

    // only add plugin if it does not exist in component-load.xml
    if (!componentExistsInRegister(componentRegister, pluginId)) {
        componentRegister.appendNode('load-component', ['component-location':pluginId])
        groovy.xml.XmlUtil.serialize(componentRegister, new FileWriter(pluginLoadFile))
        println "Activated plugin ${pluginId}"
    } else {
        println "The plugin ${pluginId} is already activated"
    }
}

def deactivatePlugin(pluginId) {
    def pluginLoadFile = "${pluginsDir}/component-load.xml"
    def componentRegister = new XmlParser().parse(pluginLoadFile)

    // Ensure that the plugin exists in component-load.xml then remove it
    if (componentExistsInRegister(componentRegister, pluginId)) {
        componentRegister.children().removeIf { plugin ->
            pluginId.equals(plugin.@"component-location")
        }
        groovy.xml.XmlUtil.serialize(componentRegister, new FileWriter(pluginLoadFile))
        println "Deactivated plugin ${pluginId}"
    } else {
        println "The plugin ${pluginId} is not active"
    }
}

def activateAndInstallPlugin(pluginId) {
    activatePlugin pluginId
    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'
    exec { commandLine gradleRunner, 'installPlugin', "-PpluginId=${pluginId}" }
}
