/*
 *  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.
 */

boolean isUsingBintray = rootProject.hasProperty('bintrayUser') && rootProject.bintrayUser &&
        rootProject.hasProperty('bintrayPassword') && rootProject.bintrayPassword

if (isUsingBintray) {
    logger.lifecycle 'Deployment environment set to Bintray'
}

def removeJarjaredDependencies = { p ->
    p.dependencies.removeAll(p.dependencies.findAll {
        it.groupId == 'org.codehaus.groovy' ||
                (['asm', 'asm-util', 'asm-analysis', 'asm-tree', 'asm-commons', 'antlr', 'commons-cli', 'openbeans'].contains(it.artifactId))
    })
}


allprojects {
    apply plugin: 'maven'
    apply from: "${rootProject.projectDir}/gradle/pomconfigurer.gradle"
}

apply from: 'gradle/backports.gradle'

allprojects {

    configurations {
        deployerJars
    }

    uploadArchives {
        repositories {
            mavenDeployer {
                configuration = configurations.deployerJars
                pom pomConfigureClosure
            }
        }
    }

    install {
        repositories {
            mavenInstaller {
                pom pomConfigureClosure
            }
        }
    }

    artifacts {
        archives jar
        archives sourceJar
        archives javadocJar
        archives groovydocJar
    }

    [uploadArchives, install]*.with {
        // dependency on jarAllAll should in theory be replaced with jar, jarWithIndy but
        // in practice, it is faster
        dependsOn([jarAllAll, sourceJar, javadocJar, groovydocJar])
        doFirst {
            if (rootProject.useIndy()) {
                new GradleException('You cannot use uploadArchives or install task with the flag [indy] turned'
                        +' on because the build handles indy artifacts by itself in that case.')
            }
            def archive = jar.archivePath
            def indyJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1]+'-indy.jar')
            if (indyJar.exists()) {
                project.artifacts.add('archives', indyJar)
            }
            def grooidJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1]+'-grooid.jar')
            if (grooidJar.exists()) {
                project.artifacts.add('archives', grooidJar)
            }
        }
    }
}

// the root project generates an alternate 'groovy-all' artifact
[uploadArchives, install]*.with {
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar, distBin])
    doFirst {
        project.artifacts.add('archives', jarAll)
        project.artifacts.add('archives', sourceAllJar)
        project.artifacts.add('archives', javadocAllJar)
        project.artifacts.add('archives', groovydocAllJar)
        project.artifacts.add('archives', distBin)
        tasks.withType(Jar).matching { it.name.startsWith('backport') }.each { t ->
            project.artifacts.add('archives', t.archivePath) {
                name = t.baseName
                type = 'jar'
            }
        }

        def archive = jarAll.archivePath
        def indyJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1] + '-indy.jar')
        if (indyJar.exists()) {
            project.artifacts.add('archives', indyJar)
        }
        def grooidJar = new File(archive.parent, archive.name[0..archive.name.lastIndexOf('.')-1]+'-grooid.jar')
        if (grooidJar.exists()) {
            project.artifacts.add('archives', grooidJar)
        }
    }
}
ext.pomAll = {
    addFilter('groovy') { artifact, file ->
        !(artifact.name.contains('groovy-all')) && !(artifact.name.contains('groovy-binary')) && !(artifact.name.contains('backport'))
    }
    addFilter('all') { artifact, file ->
        artifact.name.contains('groovy-all')
    }
    addFilter('binary') { artifact, file ->
        artifact.name.contains('groovy-binary')
    }
    project.backports.each { pkg, classes ->
        addFilter("backports-$pkg") { artifact, file ->
            artifact.name == "groovy-backports-$pkg"
        }
    }

    // regular pom
    def groovypom = pom('groovy', pomConfigureClosure)

    // pom for 'all'
    def allpom = pom('all', pomConfigureClosure)
    allpom.artifactId = 'groovy-all'

    // pom for binary zip
    def binarypom = pom('binary', pomConfigureClosureWithoutTweaks)
    binarypom.artifactId = 'groovy-binary'

    // poms for backports
    project.backports.each { pkg, classes ->
        String id = "backports-$pkg"
        def backportPom = pom(id, pomConfigureClosureWithoutTweaks)
        backportPom.artifactId = "groovy-$id"
        backportPom.whenConfigured { p ->
            p.dependencies.clear()
        }
    }

    modules().each { sp ->
        sp.install.repositories.mavenInstaller.pom.whenConfigured { subpom ->
            // add dependencies of other modules
            allpom.dependencies.addAll(subpom.dependencies)
        }
        sp.uploadArchives.repositories.mavenDeployer.pom.whenConfigured { subpom ->
            // add dependencies of other modules
            allpom.dependencies.addAll(subpom.dependencies)
        }
    }


    groovypom.whenConfigured(removeJarjaredDependencies)
    allpom.whenConfigured(removeJarjaredDependencies)

    binarypom.whenConfigured { p ->
        p.dependencies.clear()
    }
}

install {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(modules()*.install)
    repositories {
        mavenInstaller pomAll
    }
}

uploadArchives {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(modules()*.uploadArchives)
    repositories {
        mavenDeployer pomAll
    }
}

