/*
 * 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}/plugins"

// java settings
def jvmArguments = ['-Xms128M', '-Xmx1024M']
ext.ofbizMainClass = 'org.apache.ofbiz.base.start.Start'
javadoc.failOnError = true
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.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.39'
    compile 'org.apache.tomcat:tomcat-catalina:8.0.39'
    compile 'org.apache.tomcat:tomcat-jasper:8.0.39'
    compile 'org.apache.tomcat:tomcat-tribes:8.0.39'
    compile 'org.apache.xmlgraphics:fop:2.1'
    compile 'org.apache.xmlrpc:xmlrpc-client:3.1.2'
    compile 'org.apache.xmlrpc:xmlrpc-server:3.1.2'
    compile 'org.codehaus.groovy:groovy-all:2.4.5'
    compile 'org.freemarker:freemarker:2.3.25-incubating' // 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'

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

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

    // 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 ==~ '.*/+(' + componentName.tokenize(osDirSeparator).last() + ')$' ||
            entry.path ==~ /(\/+framework)$/ ||
            entry.path ==~ /(\/+applications)$/ ||
            entry.path ==~ /(\/+plugins)$/ ||
            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') {
    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('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') {
    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')
        }
    }
}
/*
 * 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') {
    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}"
    
        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")
    
        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(":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}" }
            }
        } 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 {
                installPlugin 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(":plugins:${pluginId}")) {
            throw new GradleException("Plugin \"${pluginId}\" does not exist")
        }
    }

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

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

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