/*
 *  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.codehaus.groovy.gradle.ReleaseInfoGenerator

buildscript {
    repositories {
        if (rootProject.hasProperty('buildInChina')) {
            // Try to use Aliyun maven repository when building in China
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
        }
        jcenter()
        maven{
            name 'Bintray Javadoc Hotfix repo'
            url 'http://dl.bintray.com/melix/gradle-javadoc-hotfix-plugin'
        }
        maven {
            url "https://plugins.gradle.org/m2/"
        }
        maven {
            url 'https://jitpack.io'
        }
    }

    dependencies {
        // using the old "classpath" style of plugins because the new one doesn't play well with multi-modules
        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.8'
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.3"
        classpath 'me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1'
        //classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
        classpath "gradle.plugin.org.nosphere.apache:creadur-rat-gradle:0.3.1"
        classpath "gradle.plugin.com.github.jk1:gradle-license-report:1.3"
    }
}

plugins {
    id 'com.gradle.build-scan' version '1.16'
    id 'me.champeau.buildscan-recipes' version '0.2.3'
    id 'com.github.spotbugs' version '1.6.6'
    id "com.github.ben-manes.versions" version '0.20.0'
}

buildScan {
    termsOfServiceUrl = 'https://gradle.com/terms-of-service'
    apply from: 'gradle/build-scans.gradle'
}

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

ext.modules = {
    subprojects.findAll{ !['performance'].contains(it.name) }
}
ext.isReleaseVersion = !groovyVersion.toLowerCase().endsWith("snapshot")

apply from: 'gradle/bad-practices.gradle'
//apply from: 'gradle/indy.gradle'
apply from: 'gradle/publish.gradle'
apply plugin: 'javadocHotfix'
apply plugin: "com.github.jk1.dependency-license-report"

File javaHome = new File(System.getProperty('java.home'))
logger.lifecycle "Using Java from $javaHome (version ${System.getProperty('java.version')})"

allprojects {
    apply plugin: 'java'

    buildDir = 'target'
    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    group = 'org.codehaus.groovy'
    version = groovyVersion
    repositories {
        if (rootProject.hasProperty('buildInChina')) {
            // Try to use Aliyun maven repository when building in China
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
        }
        jcenter()
        maven { url 'http://dl.bintray.com/melix/thirdparty-apache' } // openbeans
    }

    ext.buildDate = isReleaseVersion?new Date():new Date(0)

    task generateReleaseInfo(type: ReleaseInfoGenerator) {
        version = rootProject.groovyVersion
        bundleVersion = rootProject.groovyBundleVersion
        buildDate = rootProject.buildDate
        outputFile = file("$buildDir/release-info/groovy-release-info.properties")
    }

    apply plugin: 'groovy'
    apply from: "${rootProject.projectDir}/gradle/indy.gradle"
    apply from: "${rootProject.projectDir}/gradle/asciidoctor.gradle"

    tasks.withType(org.asciidoctor.gradle.AsciidoctorTask) {
        outputs.cacheIf { true }
    }

    tasks.withType(GroovyCompile) {
        groovyOptions.forkOptions.jvmArgs += ["-Dgroovy.antlr4.cache.threshold=100"]
    }
}

task(copyTestResources, type: Copy)
        .from('src/test')
        .into("$buildDir/classes/test")
        .include('**/*.txt', '**/*.xml', '**/*.properties', '**/*.png', '**/*.html', '**/*.gif', '**/*.ico', '**/*.css')
test.dependsOn(copyTestResources)

repositories {
    // todo Some repos are needed only for some configs. Declare them just for the configuration once Gradle allows this.
    maven { url 'http://repository.jboss.org/nexus/content/groups/m2-release-proxy' } // tools
    maven { url 'http://repo.bodar.com' } // tools - jarjar
}

configurations {
    compilerCompile
    tools
    antlr2
    spec
}

ext {
    antVersion = '1.10.5'
    asmVersion = '7.0'
    antlrVersion = '2.7.7'
    bridgerVersion = '1.5.Final'
    coberturaVersion = '1.9.4.1'
    commonsCliVersion = '1.4'
    gparsVersion = '1.2.1'
    ivyVersion = '2.5.0-rc1'
    jansiVersion = '1.17.1'
    jarjarVersion = '1.7.2'
    jlineVersion = '2.14.6'
    jmockVersion = '1.2.0'
    logbackVersion = '1.1.7'
    log4jVersion = '1.2.17'
    log4j2Version = '2.8'
    openbeansVersion = '1.0'
    picocliVersion = '3.8.2'
    qdoxVersion = '1.12.1'
    slf4jVersion = '1.7.25'
    xmlunitVersion = '1.6'
    xstreamVersion = '1.4.11.1'
    spockVersion = '1.2-groovy-2.4-SNAPSHOT' // supports 3.0
    antlr4Version = '4.7.2'
    spotbugsannotationsVersion = '3.1.9'
}

dependencies {
    compile "antlr:antlr:$antlrVersion"
    compile "org.ow2.asm:asm:$asmVersion"
    compile "org.ow2.asm:asm-analysis:$asmVersion"
    compile "org.ow2.asm:asm-commons:$asmVersion"
    compile "org.ow2.asm:asm-tree:$asmVersion"
    compile "org.ow2.asm:asm-util:$asmVersion"

    compile "info.picocli:picocli:$picocliVersion"
    compile "org.apache.ant:ant:$antVersion"
    compile("com.thoughtworks.xstream:xstream:$xstreamVersion") {
        exclude(group: 'xpp3', module: 'xpp3_min')
        exclude(group: 'junit', module: 'junit')
        exclude(group: 'jmock', module: 'jmock')
        exclude(group: 'xmlpull', module: 'xmlpull')
    }
    compile "com.googlecode:openbeans:$openbeansVersion"
    compile "org.fusesource.jansi:jansi:$jansiVersion"
    compile("org.apache.ivy:ivy:$ivyVersion") {
        transitive = false
    }
    compile files("${buildDir}/generated-classes")

    compileOnly "com.github.spotbugs:spotbugs-annotations:$spotbugsannotationsVersion"

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

    testCompile "jmock:jmock:$jmockVersion"
    testCompile "jmock:jmock-cglib:$jmockVersion"
    testCompile "xmlunit:xmlunit:$xmlunitVersion"
    testCompile "ch.qos.logback:logback-classic:$logbackVersion"
    testCompile "log4j:log4j:$log4jVersion"
    testCompile "org.apache.logging.log4j:log4j-core:$log4j2Version"
    testCompile "org.slf4j:jcl-over-slf4j:$slf4jVersion"
    testCompile "com.thoughtworks.qdox:qdox:$qdoxVersion"

    tools "org.pantsbuild:jarjar:$jarjarVersion"
    tools "org.jboss.bridger:bridger:$bridgerVersion"

    tools("net.sourceforge.cobertura:cobertura:$coberturaVersion") {
        exclude(module: 'asm')
        exclude(module: 'asm')
        exclude(module: 'ant')
    }
    tools "org.ow2.asm:asm:$asmVersion"
    tools "com.thoughtworks.qdox:qdox:$qdoxVersion"

    antlr2 "org.apache.ant:ant-antlr:$antVersion"

    testCompile project(':groovy-ant')
    testCompile project(':groovy-xml')
    testCompile project(':groovy-dateutil')
    testCompile project(':groovy-test')
    testCompile project(':groovy-macro')
}

ext.generatedDirectory = "${buildDir}/generated-sources"

sourceSets {
    main {
        java {
            // the only reason we add src/main/groovy here is for the bootstrap compiler
            srcDir 'src/main/groovy'
            srcDir "$generatedDirectory/src/main"
            if (!JavaVersion.current().isJava8Compatible()) {
                exclude '**/v8/*'
                exclude '**/vm8/*'
            }
        }
        groovy {
            srcDir "$generatedDirectory/src/main"
            if (!JavaVersion.current().isJava8Compatible()) {
                exclude '**/v8/*'
                exclude '**/vm8/*'
            }
        }
        resources {
            srcDirs = ['src/resources']
        }
    }
    antlr2 {
        resources {
            srcDirs = ['src/main/antlr2']
        }
    }
    test {
        groovy {
            srcDirs = ['src/test']
            if (!JavaVersion.current().isJava8Compatible()) {
                exclude '**/v8/*'
                exclude '**/vm8/*'
            }
        }
        resources {
            srcDirs = ['src/test-resources']
        }
    }
    tools {
        compileClasspath = sourceSets.main.runtimeClasspath + configurations.tools
        runtimeClasspath = output + compileClasspath
    }
}

task sourceJar(type: Jar) {
    classifier = 'sources'
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    from sourceSets.main.allSource
    from sourceSets.antlr2.allSource
}

subprojects {
    task sourceJar(type: Jar) {
        classifier = 'sources'
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        from sourceSets.main.allSource
    }
}

apply from: 'subprojects/parser-antlr4/build.gradle'

task ensureGrammars {
    outputs.cacheIf { true }
    description = 'Ensure all the Antlr2 generated files are up to date.'
    ext.antlrDirectory = "$projectDir/src/main/antlr2/org/codehaus/groovy/antlr"
    ext.javaParserDirectory = "$ext.antlrDirectory/java"
    ext.genPath = "$generatedDirectory/src/main/org/codehaus/groovy/antlr"
    ext.groovyOutDir = "$ext.genPath/parser"
    ext.javaOutDir = "$ext.genPath/java"
    inputs.dir(antlrDirectory)
    outputs.dir(groovyOutDir)
    outputs.dir(javaOutDir)
    doFirst {
        new File(groovyOutDir).mkdirs()
        new File(javaOutDir).mkdirs()
        ant {
            taskdef(name: 'antlr2',
                    classname: 'org.apache.tools.ant.taskdefs.optional.ANTLR',
                    classpath: configurations.antlr2.asPath)

            antlr2(target: "$ext.antlrDirectory/groovy.g", outputdirectory: ext.groovyOutDir) {
                classpath path: configurations.compile.asPath
            }
            antlr2(target: "$ext.javaParserDirectory/java.g", outputdirectory: ext.javaOutDir) {
                classpath path: configurations.compile.asPath
            }
        }
    }
}

compileJava {
    dependsOn ensureGrammars
    options.fork(memoryMaximumSize: javacMain_mx)

    doLast {
        ant.java(classname:'org.jboss.bridger.Bridger', classpath: rootProject.configurations.tools.asPath, outputproperty: 'stdout') {
            arg(value: "${sourceSets.main.java.outputDir.canonicalPath}/org/codehaus/groovy/runtime/DefaultGroovyMethods.class")
            arg(value: "${sourceSets.main.java.outputDir.canonicalPath}/org/codehaus/groovy/runtime/StringGroovyMethods.class")
            arg(value: "${sourceSets.main.java.outputDir.canonicalPath}/org/codehaus/groovy/classgen/Verifier.class")
        }
        ant.echo('Bridger (groovy): ' + ant.properties.stdout)
    }
}

apply from: 'wrapper.gradle'

task dgmConverter(dependsOn:compileJava) {
    outputs.cacheIf { true }

    description = 'Generates DGM info file required for faster startup.'
    def classpath = files(sourceSets.main.output.classesDirs, configurations.compile)
    ext.outputDir = file("$buildDir/dgm")

    //main = 'org.codehaus.groovy.tools.DgmConverter'
    //args = ['--info', classesDir.absolutePath]
    doFirst {
        file("$outputDir/META-INF").mkdirs()
        // we use ant.java because Gradle is a bit "too smart" with JavaExec
        // as it will invalidate the task if classpath changes, which will
        // happen once Groovy files are compiled
        ant.java(classname:'org.codehaus.groovy.tools.DgmConverter', classpath: classpath.asPath) {
            arg(value: '--info')
            arg(value: "$outputDir.absolutePath")
        }
    }
    inputs.files fileTree('src/main').include('**/*GroovyMethods.java')
    outputs.dir outputDir
}

    // Gradle classloading magic with Groovy will only work if it finds a *jar*
    // on classpath. This "bootstrap jar" contains the minimal compiler, without .groovy compiled files

task bootstrapJar(type:Jar ) {
    dependsOn compileJava, dgmConverter

    from compileJava.destinationDir
    from dgmConverter.outputDir

    destinationDir = file("$buildDir/bootstrap")
    classifier = 'bootstrap'
}

allprojects {

    tasks.withType(JavaCompile) {
        options.encoding = 'UTF-8'
        options.incremental = true

        if (classpath) {
            classpath = classpath + files(dgmConverter.outputDir)
        }
    }

    if (rootProject.indyCapable()) {
        task compileGroovyWithIndy(type: GroovyCompile) {
            source = sourceSets.main.groovy
            classpath = compileGroovy.classpath
            sourceCompatibility = 1.8
            targetCompatibility = 1.8
            groovyOptions.optimizationOptions['indy'] = true
            destinationDir = file("$buildDir/classes/indy")
        }
    }

    tasks.withType(GroovyCompile) {
        groovyOptions.fork(memoryMaximumSize: groovycMain_mx)
        groovyOptions.encoding = 'UTF-8'
        groovyClasspath = files(
                rootProject.compileJava.classpath,
                files(project==rootProject?rootProject.bootstrapJar:rootProject.jar)
        )

        // TODO: this null check was required after adding JMH plugin to performance project
        classpath = (classpath != null) ? classpath + groovyClasspath : groovyClasspath
    }
}

compileTestGroovy {
    groovyOptions.fork(memoryMaximumSize: groovycTest_mx)
}

task checkCompatibility {
    doLast {
        assert JavaVersion.current().java8Compatible
    }
}

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

// Workaround to be able to access SpotBugsTask from external gradle script.
// More info: https://discuss.gradle.org/t/buildscript-dependencies-in-external-script/23243
project.extensions.extraProperties.set('SpotBugsTask', com.github.spotbugs.SpotBugsTask)

apply from: 'gradle/test.gradle'
apply from: 'gradle/groovydoc.gradle'
apply from: 'gradle/docs.gradle'
apply from: 'gradle/assemble.gradle'
apply from: 'gradle/upload.gradle'
apply from: 'gradle/idea.gradle'
apply from: 'gradle/eclipse.gradle'
apply from: 'gradle/quality.gradle'
apply from: 'gradle/parallel-build-fixes.gradle'

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

apply from: 'gradle/signing.gradle'

licenseReport {
    excludeGroups = [
            'com.googlecode', // openbeans has no pom but is ASLv2
            'org.multiverse'  // we never include this optional dependency of an optional dependency
    ]
}

// UNCOMMENT THE FOLLOWING TASKS IF YOU WANT TO RUN LICENSE CHECKING
//task licenseFormatCustom(type:nl.javadude.gradle.plugins.license.License) {
//    source = fileTree(dir:"src").include ("**/*.java",'**/*.groovy','**/*.html','**/*.css','**/*.xml','**/*.properties','**/*.properties')
//}
//
//task licenseFormatGradle(type:nl.javadude.gradle.plugins.license.License) {
//    source = files(fileTree(dir:projectDir).include('**/*.gradle'),fileTree('buildSrc').include('**/*.groovy'))
//}
//
//licenseFormat.dependsOn licenseFormatCustom
//licenseFormat.dependsOn licenseFormatGradle
//
