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

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

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


    configurations {
        deployerJars
    }

    if (!isUsingBintray) {
        dependencies {
            deployerJars 'org.apache.maven.wagon:wagon-webdav:1.0-beta-2'
        }
    }

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

                if (!isUsingBintray) {
                    def credentials = [
                            userName: System.getProperty('groovy.deploy.username'),
                            password: System.getProperty('groovy.deploy.password')
                    ]
                    repository(id:'codehaus.org',url: uri('dav:https://dav.codehaus.org/repository/groovy'), authentication: credentials)
                    snapshotRepository(id:'codehaus.org',url: uri('dav:https://dav.codehaus.org/snapshots.repository/groovy'), authentication: credentials)
                }
            }
        }
    }

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

// the root project generates an alternate 'groovy-all' artifact
[uploadArchives, install]*.with {
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar])
    doFirst {
        project.artifacts.add('archives', jarAll)
        project.artifacts.add('archives', sourceAllJar)
        project.artifacts.add('archives', javadocAllJar)
        project.artifacts.add('archives', groovydocAllJar)
        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)
        }
    }
}
ext.pomAll = {
    addFilter('groovy') { artifact, file ->
        !(artifact.name.contains('groovy-all'))
    }
    addFilter('all') { artifact, file ->
        artifact.name.contains('groovy-all')
    }

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

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

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

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

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