/*
 * 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
 * ======================================================== */
plugins {
    id 'application'
    id 'groovy'
    id 'eclipse'
    id 'checkstyle'
    id 'maven-publish'
    id 'at.bxm.svntools' version '2.2.1' // Don't update as long as we don't use Java 11, it's needed by version 3
    id 'org.asciidoctor.convert' version '2.4.0' // About org.asciidoctor.jvm.convert as it says itself: "If you need a production-ready version of the AsciidoctorJ plugin for Gradle use a 1.5.x release of 'org.asciidoctor.convert' instead"
    id 'org.owasp.dependencycheck' version '6.0.3' apply false
    id 'se.patrikerdes.use-latest-versions' version '0.2.15' apply false
    id 'com.github.ben-manes.versions' version '0.36.0' apply false
    id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
    id "com.github.jakemarsden.git-hooks" version "0.0.2"
}

/* 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
 */
if (project.hasProperty('enableOwasp')) {
     apply plugin: 'org.owasp.dependencycheck'
}

/* DependencyUpdates plugin
 *
 * If project property "enableDependencyUpdates" is flagged then
 * gradle will download required dependencies and
 * activate Gradle's DependencyUpdates plugin and its related tasks.
 *
 * Syntax: gradlew -PenableDependencyUpdates dependencyUpdates -Drevision=release
 *
 * You may want to use the use-latest-versions plugin to help you in your work
 * Syntax:
 *  Check only: gradlew -PenableDependencyUpdates useLatestVersions && gradlew -PenableDependencyUpdates useLatestVersionsCheck
 *  Automated update: gradlew -PenableDependencyUpdates useLatestVersions
 *  Beware that this is only a help.
 *  If you use it without check you will need to check things by yourself (can be as tedious as not using this plugin)
 */
if (project.hasProperty('enableDependencyUpdates')) {
     apply plugin: 'com.github.ben-manes.versions'
     apply plugin: 'se.patrikerdes.use-latest-versions'
}

apply from: 'common.gradle'

// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.gradlew = os.contains('windows') ? 'gradlew.bat' : './gradlew'
ext.pluginsDir = "${rootDir}/plugins"

application {
    mainClassName = 'org.apache.ofbiz.base.start.Start'
    applicationDefaultJvmArgs = project.hasProperty('jvmArgs')
            ? jvmArgs.tokenize()
            : ['-Xms128M', '-Xmx1024M']
}

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

javadoc {
    title='OFBiz trunk API'
    failOnError = true
    options {
        source '8'
        encoding 'UTF-8'
        charSet 'UTF-8'
        // Those external Javadoc links should correspond to the actual
        // versions declared in the 'dependencies' block.
        links(
            'https://docs.oracle.com/javase/8/docs/api',
            'https://tomcat.apache.org/tomcat-9.0-doc/servletapi/',
            'http://docs.groovy-lang.org/docs/groovy-2.5.11/html/api',
            'https://commons.apache.org/proper/commons-cli/apidocs'
        )
    }
}

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

// Java compile options, syntax gradlew -PXlint:none build
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    if (!project.hasProperty('Xlint:none')) {
    options.compilerArgs << "-Xlint:all"
    // Exclude varargs warnings which are not silenced by @SafeVarargs.
        options.compilerArgs << "-Xlint:-varargs"
    }
}

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

// root and subproject settings
defaultTasks 'jar', 'test'

allprojects {
    repositories{
        mavenCentral()
        // the switch from jCenter to mavenCentral needs some additional repositories to be configured here
        // this should be checked frequently to remove obsolete configurations if the artifacts are available
        // on mavenCentral directly
        maven {
            // org.restlet and org.restlet.ext.servlet
            url "https://maven.restlet.talend.com"
        }
        maven {
            // net.fortuna.ical4j:ical4j:1.0-rc3-atlassian-11
            url "https://packages.atlassian.com/maven-3rdparty/"
        }
        maven {
            // org/milyn/flute/1.3/flute-1.3.jar
            // need artifact only because of wrong pom metadata in maven central
            url "https://repo1.maven.org/maven2"
            metadataSources {
                artifact()
            }
        }
        maven {
            // com.springsource.com.sun.syndication
            url "https://repo.spring.io/plugins-release"
        }
    }
}

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

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

dependencies {
    implementation 'xerces:xercesImpl:2.12.0'
    implementation 'com.google.zxing:core:3.4.1'
    implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
    implementation 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20200713.1'
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.15'
    implementation 'com.ibm.icu:icu4j:68.1'
    implementation 'com.lowagie:itext:2.1.7' // Don't update due to license change in newer versions, see OFBIZ-10455
    implementation 'com.sun.mail:javax.mail:1.6.2'
    implementation 'com.sun.syndication:com.springsource.com.sun.syndication:1.0.0'
    implementation 'com.thoughtworks.xstream:xstream:1.4.15'
    implementation 'commons-fileupload:commons-fileupload:1.4'
    implementation 'commons-net:commons-net:3.7.2'
    implementation 'commons-validator:commons-validator:1.7'
    implementation 'de.odysseus.juel:juel-impl:2.2.7'
    implementation 'net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12'
    implementation 'net.lingala.zip4j:zip4j:2.6.4'
    implementation 'org.apache.ant:ant-junit:1.10.9'
    implementation 'org.apache.commons:commons-collections4:4.4'
    implementation 'org.apache.commons:commons-dbcp2:2.8.0'
    implementation '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."
    implementation 'org.apache.commons:commons-text:1.9'
    implementation 'org.apache.geronimo.components:geronimo-transaction:3.1.4'
    implementation 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    implementation 'org.apache.httpcomponents:httpclient-cache:4.5.13'
    implementation 'org.apache.logging.log4j:log4j-api:2.14.0' // the API of log4j 2
    implementation 'org.apache.logging.log4j:log4j-core:2.14.0' // Somehow needed by Buildbot to compile OFBizDynamicThresholdFilter.java
    implementation 'org.apache.poi:poi:4.1.2'
    implementation 'org.apache.pdfbox:pdfbox:2.0.24'
    implementation 'org.apache.shiro:shiro-core:1.7.1'
    implementation 'org.apache.sshd:sshd-core:1.7.0' // So far we did not update from 1.7.0 because of a compile issue. You may try w/ a newer version than  2.4.0
    implementation 'org.apache.tika:tika-core:1.26'
    implementation 'org.apache.tika:tika-parsers:1.25'
    implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.48' // Remember to change the version number (9 now) in javadoc block if needed.
    implementation 'org.apache.tomcat:tomcat-jasper:9.0.48'
    implementation 'org.apache.axis2:axis2-kernel:1.7.9'
    implementation 'batik:batik-svg-dom:1.6-1'
    implementation 'org.apache.xmlgraphics:fop:2.3' // NOTE: since 2.4 dependencies are messed up. See https://github.com/moqui/moqui-fop/blob/master/build.gradle
    implementation 'org.apache.xmlrpc:xmlrpc-client:3.1.3'
    implementation 'org.apache.xmlrpc:xmlrpc-server:3.1.3'
    implementation 'org.codehaus.groovy:groovy-all:2.5.11' // Compile issue with commons-cli and Groovy 3. Remember to change the version number in javadoc block.
    implementation 'org.freemarker:freemarker:2.3.31' // Remember to change the version number in FreeMarkerWorker class when upgrading. See OFBIZ-10019 if >= 2.4
    implementation 'org.owasp.esapi:esapi:2.2.2.0'
    implementation 'org.springframework:spring-test:5.3.2'
    implementation 'org.zapodot:jackson-databind-java-optional:2.6.1'
    implementation 'oro:oro:2.0.8'
    implementation 'wsdl4j:wsdl4j:1.6.3'
    implementation 'com.auth0:java-jwt:3.11.0'
    implementation 'org.jdom:jdom:1.1.3' // don't upgrade above 1.1.3, makes a lot of not obvious and useless complications, see last commits of OFBIZ-12092 for more

    testImplementation 'org.hamcrest:hamcrest-library:2.2' // Enable junit4 to not depend on hamcrest-1.3
    testImplementation 'org.mockito:mockito-core:3.6.28'
    testImplementation 'org.jmockit:jmockit:1.49'
    testImplementation 'com.pholser:junit-quickcheck-generators:1.0'

    runtimeOnly 'javax.xml.soap:javax.xml.soap-api:1.4.0'
    runtimeOnly 'de.odysseus.juel:juel-spi:2.2.7'
    runtimeOnly 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
    runtimeOnly 'net.sf.barcode4j:barcode4j:2.1'
    runtimeOnly 'org.apache.axis2:axis2-transport-http:1.7.9'
    runtimeOnly 'org.apache.axis2:axis2-transport-local:1.7.9'
    runtimeOnly 'org.apache.derby:derby:10.14.2.0'  // So far we did not update from 10.14.2.0 because of a compile issue. You may try w/ a newer version than 10.15.1.3
    runtimeOnly 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:2.1'
    runtimeOnly 'org.apache.logging.log4j:log4j-1.2-api:2.14.0' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jul:2.14.0' // for external jars using the java.util.logging: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl:2.14.0' // for external jars using slf4j: routes logging to log4j 2
    runtimeOnly 'org.apache.logging.log4j:log4j-jcl:2.14.0' // need to constrain to version to avoid classpath conflict (ReflectionUtil)
    runtimeOnly 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

    // Dependencies defined by the plugins
    subprojects.each { subProject ->
        implementation project(path: subProject.path, configuration: 'pluginLibsCompile')
        runtimeOnly project(path: subProject.path, configuration: 'pluginLibsRuntime')
        compileOnly project(path: subProject.path, configuration: 'pluginLibsCompileOnly')
    }

    junitReport 'junit:junit:4.13.1'
    junitReport 'org.apache.ant:ant-junit:1.10.9'
    asciidoctor 'org.asciidoctor:asciidoctorj-pdf:1.5.3'
    asciidoctor 'org.jruby:jruby-complete:9.2.14.0' // bug workaround - see OFBIZ-9873

    // Libraries downloaded manually
    implementation fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
        implementation fileTree(dir: libDir, include: '**/*.jar')
    }
}

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

sourceSets {
    main {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            exclude excludedJavaSources
        }
        groovy {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/groovy')
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/resources')
            srcDirs += getDirectoryInActiveComponentsIfExists('config')
            srcDirs += getDirectoryInActiveComponentsIfExists('dtd')
        }
    }

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

    groovyScripts {
        groovy {
            srcDirs += getDirectoryInActiveComponentsIfExists('groovyScripts')
            compileClasspath += sourceSets.main.compileClasspath
            compileClasspath += sourceSets.main.output
        }
    }
}

tasks.named('compileGroovyScriptsGroovy') {
    // We don't want to build groovyScripts as they should be considered as standalone elements executed in
    // isolation by ofbiz. Building them will result in numerous error due to duplicated classes.
    enabled = false
}

jar.manifest.attributes(
    'Implementation-Title': project.name,
    'Main-Class': application.mainClassName,
    'Class-Path': getJarClasspath()
)

// Checks OFBiz Java coding conventions.
checkstyle {
    // Defining a maximum number of “tolerated” errors ensures that
    // this number cannot increase in the future. It corresponds to
    // the sum of errors found last time it was changed after using the
    // ‘checkstyle’ tool present in the framework and in the official
    // plugins.
    tasks.checkstyleMain.maxErrors = 116
    // Currently there are still errors so we need to temporarily
    // hide them to avoid polluting the terminal output.
    showViolations = false
}
gitHooks {
    hooks = ['pre-push': 'checkstyleMain']
}

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

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

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

test {
    jvmArgs "-javaagent:${classpath.find { it.name.contains("jmockit") }.absolutePath}"
}

/* ========================================================
 * 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'])
    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', [])

    if (project.hasProperty('tenantId')) {
        executeLoadTenant.args '--load-data', "delegator=default#${tenantId}"
    }
    if (project.hasProperty('tenantReaders')) {
        executeLoadTenant.args '--load-data', "readers=${tenantReaders}"
    }
    if (project.hasProperty('tenantComponent')) {
        executeLoadTenant.args '--load-data', "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'])
    loadTenantOnMasterTenantDb.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)

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

    // Load the tenant admin user account
    createOfbizCommandTask('loadTenantAdminUserLogin', [])
    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', "delegator=default#${tenantId}"
        loadTenantAdminUserLogin.args(
            '--load-data', "delegator=default#${tenantId}",
            '--load-data', "file=${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml"
        )
    }
    if (project.hasProperty('tenantReaders')) {
        loadTenantData.args '--load-data', "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',
        'revnumber': 'Trunk',
        'experimental': '',
        'allow-uri-read': true,
        'icons': 'font',
        'sectnums': '',
        'chapter-label': '',
        'toc': 'left@',
        'toclevels': '3'
}

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

task deletePluginDocumentation {
    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'
        activeComponents().each { component ->
            copy {
                from "${component}/src/docs/asciidoc/images/${component.name}"
                include '**/*.*'
                into "${rootDir}/docs/asciidoc/images/${component.name}"
            }
        }
    sourceDir "${rootDir}/docs/asciidoc"
    outputDir file("${buildDir}/asciidoc/ofbiz")
    doLast {
      activeComponents().each { component ->
          delete "${rootDir}/docs/asciidoc/images/${component.name}"
      }
    }
}

task generatePluginDocumentation(group: docsGroup) {
    dependsOn deletePluginDocumentation
    description 'Generate plugin documentation. Expects pluginId flag'
    activeComponents()
        .findAll { project.hasProperty('pluginId') && it.name == pluginId }
        .each { component ->
            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 ->
        activeComponents().each { 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()}"
    }
}

// ========== 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', 'dtd', 'entitydef', 'lib', 'patches/test', 'patches/qa',
                'patches/production', 'groovyScripts', 'minilang', 'servicedef', 'src/main/java', 'src/test/java', 'testdef',
                'widget', "webapp/${webappName}/error", "webapp/${webappName}/WEB-INF"].each {
            mkdir pluginDir+'/'+it
        }

        [   [tempName:'ofbiz-component.xml', newName:'ofbiz-component.xml', location:''],
            [tempName:'build.gradle', newName:'build.gradle', location:''],
            [tempName:'TypeData.xml', newName:"${pluginResourceName}TypeData.xml", location:'data'],
            [tempName:'SecurityPermissionSeedData.xml', newName:"${pluginResourceName}SecurityPermissionSeedData.xml", location:'data'],
            [tempName:'SecurityGroupDemoData.xml', newName:"${pluginResourceName}SecurityGroupDemoData.xml", location:'data'],
            [tempName:'DemoData.xml', newName:"${pluginResourceName}DemoData.xml", location:'data'],
            [tempName:'HELP.adoc', newName:'HELP.adoc', location:''],
            [tempName:'README.adoc', newName:'README.adoc', location:''],
            [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:'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')) {
        activeComponents()
            .findAll { it.name == pluginId }
            .each { component ->
                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')) {
        // GitHub SVN feature https://docs.github.com/en/github/importing-your-projects-to-github/working-with-subversion-on-github/support-for-subversion-clients
        task pullPluginFromSvn(type: SvnCheckout) {
            svnUrl = "https://github.com/apache/ofbiz-plugins/trunk/${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) {
        // GitHub SVN feature https://docs.github.com/en/github/importing-your-projects-to-github/working-with-subversion-on-github/support-for-subversion-clients
        svnUrl = "https://github.com/apache/ofbiz-plugins/trunk"
        workspaceDir = "${pluginsDir}"
    }
    dependsOn pullPluginsFromSvn

    task installAllPlugins {
        subdirs(file("${pluginsDir}"))
            .filter(this.isComponentEnabled)
            .filter { taskExistsInproject(":plugins:${it.name}", 'install') }
            .forEach({ plugin ->
                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
    }
}
/*
 * Keep this task below all other clean tasks  The location of
 * declaration is important because it means that it will automatically
 * run whenever the task cleanAll executes (dependency matched by regex)
 */
def cleanTasks = tasks.findAll { it.name ==~ /^clean.+/ }
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
    description 'Execute all cleaning tasks.'
}

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

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

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) {
    task(type: JavaExec, dependsOn: classes, taskName) {
        jvmArgs(application.applicationDefaultJvmArgs)
        classpath = sourceSets.main.runtimeClasspath
        main = application.mainClassName
        args arguments
        if (taskName ==~ /^ofbiz.*(--test|-t).*/) {
            finalizedBy(createTestReports)
        }
    }
}

def createOfbizBackgroundCommandTask(taskName) {
    def sourceTask = taskName.tokenize().first()
    def arguments = (taskName - sourceTask)
    def serverCommand = "ofbiz ${arguments}".toString()

    task (taskName) {
        doLast {
            spawnProcess([gradlew, "--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) {
    activeComponents()
        .collect { file(it.toString() + '/' + dirName) }
        .findAll { it.exists() }
}

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

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

def getJarClasspath() {
    def mapper = os.contains('windows') ? { '\\' + "$it" } : { "$it" }
    configurations.runtimeClasspath.collect(mapper).join(' ')
}

def subprojectExists(fullyQualifiedProject) {
    subprojects.stream()
        .anyMatch { it.path == fullyQualifiedProject.toString() }
}

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

def gradlewSubprocess(commandList) {
    exec { commandLine(gradlew, "--no-daemon", *commandList) }
}


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

tasks.startScripts {
    doLast {
        // Alter the start script for Unix systems.
        unixScript.text =
                unixScript.text.replace('CLASSPATH=$APP_HOME/lib','CLASSPATH=$APP_HOME/config/:$APP_HOME/lib-extra/*:$APP_HOME/lib')
        // Alter the start script for Windows systems.
        windowsScript.text =
                windowsScript.text.replace('CLASSPATH=%APP_HOME%\\lib',
 'CLASSPATH=%APP_HOME%\\conf\\;%APP_HOME%\\lib-extra\\*;%APP_HOME%\\lib')
    }
}
