/*
 *  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 'me.champeau.buildscan-recipes' version '0.2.3'
    id 'com.github.ben-manes.versions' version '0.51.0'
    id 'com.github.blindpirate.osgi' version '0.0.7'
    id 'com.github.jk1.dependency-license-report' version '2.7'
    id 'org.sonarqube' version '5.0.0.4638'
    id 'org.apache.groovy-core'
    id 'java-test-fixtures'
    id 'org.apache.groovy-jacoco-aggregation'
}

buildScanRecipes {
    recipe 'git-commit', baseUrl: 'https://github.com/apache/groovy/tree'
    recipe 'teamcity', baseUrl: 'https://ci.groovy-lang.org', guest: 'true'
    recipes 'git-status', 'gc-stats', 'teamcity', 'travis-ci'
}

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.fusesource.jansi:jansi:${versions.jansi}"

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

    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.jacksonDatabind}"
    testImplementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${versions.jackson}"
    testImplementation "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"

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

    tools "com.eed3si9n.jarjar:jarjar:${versions.jarjar}"
    tools "org.jboss.bridger:bridger:${versions.bridger}"
    tools "org.ow2.asm:asm:${versions.asm}"
    tools "com.thoughtworks.qdox:qdox:${versions.qdox}"

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

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

configurations {
    javadocClasspath.extendsFrom(
            loggingImplementation,
            xstreamAstImplementation,
            gparsImplementation,
            grapesImplementation
    )
    groovyCompilerClasspath {
        extendsFrom(implementation, compileOnly, 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'
}
