/*
 *  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.
 */
plugins {
    id 'com.github.ben-manes.versions' version '0.53.0'
    id 'io.github.goooler.osgi' version '0.8.6'
    id 'com.github.jk1.dependency-license-report' version '2.9'
    id 'org.sonarqube' version '6.2.0.5505'
    id 'org.apache.groovy-core'
    id 'java-test-fixtures'
    id 'org.apache.groovy-jacoco-aggregation'
}

base {
    archivesName = 'groovy'
}

groovyLibrary {
    registerOptionalFeature 'gpars'
    registerOptionalFeature 'grapes'
    registerOptionalFeature 'logging'
    registerOptionalFeature 'xstreamAst'

    repackagedDependencies = [
            'antlr', 'antlr-runtime', 'antlr4', 'antlr4-runtime', 'antlr4-annotations',
            'asm', 'asm-commons', 'asm-tree', 'asm-util', 'picocli'
    ]

    withGrooid(
            "org.apache.groovy:groovy-grooid:${sharedConfiguration.groovyVersion.get()}",
            ['openbeans'] as Set,
            [
                    'com.googlecode.openbeans.**': 'groovyjarjaropenbeans.@1',
                    'org.apache.harmony.beans.**': 'groovyjarjarharmonybeans.@1',
                    'java.beans.**': 'groovyjarjaropenbeans.@1'
            ],
            [
                    '*': ['META-INF/NOTICE']
            ],
            ['META-INF/NOTICE', 'META-INF/INDEX.LIST'],
            [
                    (project.relativePath(rootProject.file('notices/NOTICE-GROOIDJARJAR'))): 'META-INF/NOTICE'
            ]
    )
}

groovyCore {
    def supportClasses = ['Boolean','Char','Byte','Short','Int','Long','Float','Double'].collect {
        'org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport$'+it+'ArrayStaticTypesHelper'
    }

    bridgedClasses *supportClasses,
            'org.codehaus.groovy.classgen.Verifier',
            'org.codehaus.groovy.ast.tools.GeneralUtils',
            'org.codehaus.groovy.ast.stmt.TryCatchStatement',
            'org.codehaus.groovy.runtime.StringGroovyMethods',
            'org.codehaus.groovy.runtime.DefaultGroovyMethods',
            'org.codehaus.groovy.transform.stc.DefaultTypeCheckingExtension'

    excludeFromJavadoc '**/GroovyRecognizer.java', '*.g4' // generated file
}

dependencies {
    // for internal CLI usage
    api "info.picocli:picocli:${versions.picocli}" // marked as api but manually excluded later in assemble.gradle - modules will use shaded version
    // for internal usage of things like Opcode
    api "org.ow2.asm:asm:${versions.asm}" // marked as api but manually excluded later in assemble.gradle - modules will use shaded version
    // for internal usage by the parser but manually excluded later in assemble.gradle - modules will use shaded version
    implementation "org.ow2.asm:asm-analysis:${versions.asm}"
    implementation "org.ow2.asm:asm-commons:${versions.asm}"
    implementation "org.ow2.asm:asm-tree:${versions.asm}"
    implementation "org.ow2.asm:asm-util:${versions.asm}"
    implementation "me.champeau.openbeans:openbeans:${versions.openbeans}"
    implementation "me.sunlan:antlr4-runtime:${versions.antlr4}"

    antlr "me.sunlan:antlr4:${versions.antlr4}"

    gparsImplementation "org.codehaus.gpars:gpars:${versions.gpars}", {
        exclude(group: 'org.codehaus.groovy', module: 'groovy-all')
    }

    grapesImplementation "org.apache.ivy:ivy:${versions.ivy}", {
        transitive = false
    }

    loggingImplementation "org.jline:jansi:${versions.jline}"

    xstreamAstImplementation "com.thoughtworks.xstream:xstream:${versions.xstream}", {
        exclude group: 'jmock'  , module: 'jmock'
        exclude group: 'junit'  , module: 'junit'
        exclude group: 'xmlpull', module: 'xmlpull'
        exclude group: 'xpp3'   , module: 'xpp3_min'
    }

    testImplementation projects.groovyAnt
    testImplementation projects.groovyXml
    testImplementation projects.groovyJson
    testImplementation projects.groovyTest
    testImplementation projects.groovyMacro
    testImplementation projects.groovyDateutil
    testImplementation "net.jcip:jcip-annotations:${versions.jcipAnnotations}"
    testImplementation "ch.qos.logback:logback-classic:${versions.logback}"
    testImplementation "log4j:log4j:${versions.log4j}"
    testImplementation "org.apache.logging.log4j:log4j-core:${versions.log4j2}"
    testImplementation "org.slf4j:jcl-over-slf4j:${versions.slf4j}"
    testImplementation "com.thoughtworks.qdox:qdox:${versions.qdox}"
    testImplementation "com.fasterxml.jackson.core:jackson-databind:${versions.jackson}"
    testImplementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${versions.jackson}"

    testFixturesImplementation projects.groovyXml
    testFixturesImplementation projects.groovyTest
    testFixturesImplementation "xmlunit:xmlunit:${versions.xmlunit}"

    tools "com.eed3si9n.jarjar:ant-jarjar:${versions.jarjar}"
    tools "org.apache.ant:ant:${versions.ant}"
    tools "org.jboss.bridger:bridger:${versions.bridger}"
    // updated bridger dependencies to remove vulnerabilities:
    tools "com.jcraft:jsch:0.1.55"
    tools "commons-io:commons-io:2.20.0"
    tools "org.apache.maven:maven-core:3.9.11"
    tools "org.apache.maven.shared:maven-shared-utils:3.4.2"
    tools "org.codehaus.plexus:plexus-utils:4.0.2"
    // end
    tools "org.ow2.asm:asm:${versions.asm}"
    tools "com.thoughtworks.qdox:qdox:${versions.qdox}"

    spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.14.0'

    testRuntimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}"
    testRuntimeOnly(project(':')) {
        because 'Tests are using Grapes'
        capabilities {
            requireCapability 'org.apache.groovy:groovy-grapes'
        }
    }
    testRuntimeOnly(project(':')) {
        because 'Tests are using GPars'
        capabilities {
            requireCapability 'org.apache.groovy:groovy-gpars'
        }
    }
}

configurations {
    javadocClasspath.extendsFrom(
            loggingImplementation,
            xstreamAstImplementation,
            gparsImplementation,
            grapesImplementation
    )
    groovyCompilerClasspath {
        extendsFrom(implementation, compileOnly, gparsImplementation, grapesImplementation, loggingImplementation, xstreamAstImplementation, runtimeOnly)
    }
}

allprojects {
    tasks.withType(AbstractCopyTask).configureEach {
        it.duplicatesStrategy = DuplicatesStrategy.WARN
    }
}

tasks.named('jar') {
    metaInf {
        from("$projectDir/licenses/LICENSE-JARJAR")
        from("$projectDir/licenses") {
            into('licenses')
            include('asm-license.txt')
            include('antlr4-license.txt')
        }
        from("$projectDir/notices/NOTICE-JARJAR")
        rename '^([A-Z]+)-([^.]*)', '$1'
    }
    exclude '**/package-info.class'
}


// some tests require Jars, but those are not allowed in the source directory
// by the Apache policy, so we need to build them and add them to the test
// resources classpath

def extModuleFixtureDir = project.layout.projectDirectory.dir('src/test-fixtures/extmodule')
def extModuleOutputDir = project.layout.buildDirectory.dir('testFixtures/extmodule')
def extModuleRepoDir = extModuleOutputDir.map { it.dir('repo') }

def compileTestExtensionModule = tasks.register('compileTestExtensionModule', JavaCompile) {
    classpath = files(tasks.named('jar'))
    source fileTree(extModuleFixtureDir.dir('src/main/java'))
    destinationDirectory = extModuleOutputDir.map  { it.dir('classes') }
    sourceCompatibility = sharedConfiguration.targetJavaVersion.get()
    targetCompatibility = sharedConfiguration.targetJavaVersion.get()
}

def testExtensionModuleJar = tasks.register('testExtensionModuleJar', Jar) {
    description = 'Builds a sample extension module used in tests'
    archiveBaseName = 'module-test'
    archiveVersion = '1.4'
    from compileTestExtensionModule
    from extModuleFixtureDir.dir('src/main/resources')
    // emulate Maven repo format for output
    destinationDirectory = extModuleRepoDir.map { it.dir("jars/module-test/module-test/${archiveVersion.get()}") }
}

dependencies {
    testRuntimeOnly files(extModuleRepoDir)
}

tasks.named('test') {
    dependsOn testExtensionModuleJar
}

if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16)) {
    logger.lifecycle '''
************************************* WARNING ***********************************************
****  You're running the build with an older JDK. NEVER try to release with an old JDK!  ****
****  You must use a JDK 16+ in order to compile all features of the language.           ****
*********************************************************************************************
'''
}

apply from: 'gradle/licenses.gradle'

// CC: This can probably be removed as the native IDEA import
// works pretty nice, but it's up to the Groovy devs to decide
apply from: 'gradle/idea.gradle'
apply from: 'gradle/eclipse.gradle'

// If a local configuration file for tweaking the build is present, apply it
if (file('user.gradle').exists()) {
    apply from: 'user.gradle'
}

licenseReport {
    excludeGroups = [
            'org.multiverse'  // we never include this optional dependency of an optional dependency
    ]
}

sonarqube {
    properties {
        property 'sonar.projectName', 'Apache Groovy'
        property 'sonar.projectKey', 'apache_groovy'
        property 'sonar.organization', 'apache'
        property 'sonar.host.url', 'https://sonarcloud.io'
        property 'sonar.cpd.exclusions', '**/*'
//        property 'sonar.coverage.jacoco.xmlReportPaths', layout.buildDirectory.file('reports/jacoco/jacocoAllReport/jacocoAllReport.xml').get().asFile.absolutePath
    }
}

def UNSTABLE = /^([\d.-]+(alpha|beta|rc|m)[\d.-]+(groovy[\d.-]+)?|20030203.000550|20031129.200437|200404\d\d|2004-03-19)$/
// ignore non-stable releases
tasks.named('dependencyUpdates')?.configure {
    gradleReleaseChannel = 'current'
    rejectVersionIf {
        !(it.currentVersion.toLowerCase() ==~ UNSTABLE) && it.candidate.version.toLowerCase() ==~ UNSTABLE
    }
}

artifacts {
    grapesRuntimeElements file: jar.archiveFile.get().asFile, type: 'jar'
    xstreamAstRuntimeElements file: jar.archiveFile.get().asFile, type: 'jar'
    gparsRuntimeElements file: jar.archiveFile.get().asFile, type: 'jar'
    loggingRuntimeElements file: jar.archiveFile.get().asFile, type: 'jar'
}
