/*
 *  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 isUsingArtifactory = rootProject.hasProperty('artifactoryUser') && rootProject.artifactoryUser &&
        rootProject.hasProperty('artifactoryPassword') && rootProject.artifactoryPassword

if (isUsingArtifactory) {
    logger.lifecycle 'Deployment environment set to Artifactory'
}

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

allprojects {
    if (project == rootProject || modules().contains(project)) {
        apply plugin: 'maven'
        apply from: "${rootProject.projectDir}/gradle/pomconfigurer.gradle"
        install.dependsOn checkCompatibility
    }
}

apply from: 'gradle/backports.gradle'

ext.basename = { String s -> s.take(s.lastIndexOf('.')) }
ext.deriveFile = { File archive, String suffix -> new File(archive.parent, basename(archive.name) + "-${suffix}.jar") }

allprojects {
    if (project == rootProject || modules().contains(project)) {
        ext.signWithClassifier = { String c, File f ->
            if (rootProject.isReleaseVersion) {
                signing.sign(c, f)
                def ascFile = new File(f.parent, f.name + '.asc')
                if (ascFile.exists()) {
                    project.artifacts.add('archives', ascFile) {
                        classifier = c
                        type = 'asc'
                        extension = 'jar.asc'
                    }
                }
            }
        }

        ext.signArchiveTask = { archiveTask ->
            if (rootProject.isReleaseVersion) {
                signing.sign(archiveTask.classifier, archiveTask.archivePath)
                def ascFile = new File(archiveTask.destinationDir, archiveTask.archiveName + '.asc')
                if (ascFile.exists()) {
                    project.artifacts.add('archives', ascFile) {
                        name = archiveTask.baseName
                        classifier = archiveTask.classifier
                        type = 'asc'
                        extension = archiveTask.extension + '.asc'
                    }
                }
            }
        }

        uploadArchives {
            repositories {
                mavenDeployer {
                    pom pomConfigureClosure
                    beforeDeployment { MavenDeployment deployment -> if (rootProject.isReleaseVersion) signing.signPom(deployment) }
                }
            }
        }

        install {
            repositories {
                mavenInstaller {
                    pom pomConfigureClosure
                    beforeDeployment { MavenDeployment deployment -> if (rootProject.isReleaseVersion) signing.signPom(deployment) }
                }
            }
        }

        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 indyJar = rootProject.ext.deriveFile(jar.archivePath, 'indy')
                if (indyJar.exists()) {
                    project.artifacts.add('archives', indyJar)
                }
                def grooidJar = rootProject.ext.deriveFile(jar.archivePath, 'grooid')
                if (grooidJar.exists()) {
                    project.artifacts.add('archives', grooidJar)
                }
            }
        }

        install {
            doFirst {
                // gradle doesn't expect us to mutate configurations like we do here
                // so signing the configuration won't work and we do it manually here
                signArchiveTask(jar)
                signArchiveTask(sourceJar)
                signArchiveTask(javadocJar)
                signArchiveTask(groovydocJar)
                def indyJar = rootProject.ext.deriveFile(jar.archivePath, 'indy')
                if (indyJar.exists()) {
                    signWithClassifier('indy', indyJar)
                }
                def grooidJar = rootProject.ext.deriveFile(jar.archivePath, 'grooid')
                if (grooidJar.exists()) {
                    signWithClassifier('grooid', grooidJar)
                }
            }
        }
    }
}

// the root project generates several alternate artifacts, e.g. 'groovy-all'
// we don't want them in the root project so add them as artifacts with a modified name
// we'll exclude the original artifacts during publication with an exclude pattern
[uploadArchives, install]*.with {
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar, distBin, distDoc, dist, distBin])
    doFirst {
        project.artifacts.add('archives', jarAll) {
            name = 'groovy-all'
        }
        project.artifacts.add('archives', sourceAllJar) {
            name = 'groovy-all'
        }
        project.artifacts.add('archives', javadocAllJar) {
            name = 'groovy-all'
        }
        project.artifacts.add('archives', groovydocAllJar) {
            name = 'groovy-all'
        }
        project.artifacts.add('archives', distBin) {
            name = 'groovy-binary'
        }
        signArchiveTask(jarAll)
        signArchiveTask(sourceAllJar)
        signArchiveTask(javadocAllJar)
        signArchiveTask(groovydocAllJar)

        // TODO rework these?
        if (isReleaseVersion) {
            signing.sign(distBin.archivePath)
            def ascFile = new File(distBin.destinationDir, distBin.archiveName + '.asc')
            if (ascFile.exists()) {
                project.artifacts.add('archives', ascFile) {
                    name = 'groovy-binary'
                    type = 'asc'
                    extension = 'zip.asc'
                }
            }
            signing.sign(distSrc.archivePath)
            signing.sign(distDoc.archivePath)
            signing.sign(dist.archivePath)
        }

        tasks.withType(Jar).matching { it.name.startsWith('backport') }.each { t ->
            project.artifacts.add('archives', t.archivePath) {
                name = t.baseName
                type = 'jar'
                classifier = t.classifier
            }
            if (isReleaseVersion) {
                signing.sign(t.classifier, t.archivePath)
                def ascFile = new File(t.destinationDir, t.archiveName + '.asc')
                if (ascFile.exists()) {
                    project.artifacts.add('archives', ascFile) {
                        name = t.baseName
                        classifier = t.classifier
                        type = 'asc'
                        extension = t.extension + '.asc'
                    }
                }
            }
        }

        def indyJar = deriveFile(jarAll.archivePath, 'indy')
        if (indyJar.exists()) {
            project.artifacts.add('archives', indyJar)
            signWithClassifier('indy', indyJar)
        }
        def grooidJar = deriveFile(jarAll.archivePath, 'grooid')
        if (grooidJar.exists()) {
            project.artifacts.add('archives', grooidJar)
            signWithClassifier('grooid', 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()
    }

    beforeDeployment { MavenDeployment deployment -> if (isReleaseVersion) signing.signPom(deployment) }
}

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