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'].contains(it.artifactId))
    })
}


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

        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')) && !(artifact.name.contains('groovy-binary'))
    }
    addFilter('all') { artifact, file ->
        artifact.name.contains('groovy-all')
    }
    addFilter('binary') { artifact, file ->
        artifact.name.contains('groovy-binary')
    }

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

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