/*
 *  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.6'
    id "com.github.jk1.dependency-license-report" version "1.3"
    id 'org.sonarqube' version '3.5.0.2730'
    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'
}

archivesBaseName = '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 {
    bridgedClasses 'org.codehaus.groovy.runtime.DefaultGroovyMethods',
            'org.codehaus.groovy.runtime.StringGroovyMethods',
            'org.codehaus.groovy.classgen.Verifier',
            'org.codehaus.groovy.ast.tools.GeneralUtils'

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

    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')
    }
    grapesImplementation("org.apache.ivy:ivy:${versions.ivy}") {
        transitive = false
    }

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

    testImplementation projects.groovyAnt
    testImplementation projects.groovyXml
    testImplementation projects.groovyJson
    testImplementation projects.groovyTest
    testImplementation projects.groovyMacro
    testImplementation projects.groovyDateutil
    testImplementation "jmock:jmock:${versions.jmock}"
    testImplementation "jmock:jmock-cglib:${versions.jmock}"
    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}"

    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("net.sourceforge.cobertura:cobertura:${versions.cobertura}") {
        exclude(group: 'asm')
        exclude(group: 'org.ow2.asm')
        exclude(module: 'ant')
    }
    tools "org.ow2.asm:asm:${versions.asm}"
    tools "com.thoughtworks.qdox:qdox:${versions.qdox}"

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

    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 = 1.8
    targetCompatibility = 1.8
}

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
}

clean.doFirst {
    delete "${rootDir}/buildSrc"
}

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