/*
 *  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', 'picocli', 'openbeans']
def removeJarjaredDependencies = { p ->
    p.dependencies.removeAll(p.dependencies.findAll {
        it.groupId == 'org.apache.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.addSigFile = { File sigFile, c, ext, n ->
            if (sigFile.exists()) {
                project.artifacts.add('archives', sigFile) {
                    if (n) {
                        name = n
                    }
                    classifier = c
                    type = 'asc'
                    extension = ext
                }
            }
        }
        ext.signWithClassifier = { String c, File f ->
            if (rootProject.isReleaseVersion) {
                signing.sign(c, f)
                def ascFile = new File(f.parent, f.name + '.asc')
                addSigFile(ascFile, c, 'jar.asc', null)
            }
        }
        ext.signWithName = { String baseName, File f ->
            if (rootProject.isReleaseVersion) {
                signing.sign(null, f)
                def ascFile = new File(f.parent, f.name + '.asc')
                addSigFile(ascFile, null, 'jar.asc', baseName)
            }
        }
        ext.signArchiveTask = { archiveTask ->
            if (rootProject.isReleaseVersion) {
                signing.sign(archiveTask.classifier, archiveTask.archivePath)
                def ascFile = new File(archiveTask.destinationDir, archiveTask.archiveName + '.asc')
                addSigFile(ascFile, archiveTask.classifier, archiveTask.extension + '.asc', archiveTask.baseName)
            }
        }

        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 jarjar.outputFile
            archives sourceJar
            archives javadocJar
            archives groovydocJar
        }

        configurations.archives.with {
            artifacts.removeAll(artifacts.find { it.name =~ 'raw' } )
        }

        [uploadArchives, install]*.with {
            dependsOn([grooidjar, jarjar, sourceJar, javadocJar, groovydocJar])
            doFirst {
                def grooidJarFile = rootProject.ext.deriveFile(jarjar.outputFile, 'grooid')
                if (grooidJarFile.exists()) {
                    project.artifacts.add('archives', grooidJarFile)
                }
            }
        }

        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
                signWithName(jar.baseName, jarjar.outputFile)
                signArchiveTask(sourceJar)
                signArchiveTask(javadocJar)
                signArchiveTask(groovydocJar)
                def grooidJarFile = rootProject.ext.deriveFile(jarjar.outputFile, 'grooid')
                if (grooidJarFile.exists()) {
                    signWithClassifier('grooid', grooidJarFile)
                }
            }
        }
    }
}

// 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
def configureAdditionalArtifacts = {
    project.artifacts.add('archives', distBin) { name = 'groovy-binary' }
    project.artifacts.add('archives', sourceAllJar) { name = 'groovy-all' }
    project.artifacts.add('archives', javadocAllJar) { name = 'groovy-all' }
    project.artifacts.add('archives', groovydocAllJar) { name = 'groovy-all' }
    signArchiveTask(sourceAllJar)
    signArchiveTask(javadocAllJar)
    signArchiveTask(groovydocAllJar)

    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 optionalModules = [
        'groovy-astbuilder',
        'groovy-bsf',
        'groovy-cli-commons',
        'groovy-dateutil',
        'groovy-jaxb',
        'groovy-yaml'
]

def pomAll = {
    addFilter('groovy') { artifact, file ->
        !(artifact.name.contains('groovy-all')) &&
                !(artifact.name.contains('groovy-binary')) &&
                !(artifact.name.contains('groovy-bom')) &&
                !(artifact.name.contains('backport'))
    }
    addFilter('all') { artifact, file ->
        // add an arbitrary artifact, so that the pom file is generated
        // we adjust the packaging attribute later
        artifact.name.contains('groovy-binary')
    }
    addFilter('bom') { artifact, file ->
        // add an arbitrary artifact, so that the pom file is generated
        // we adjust the packaging attribute later
        artifact.name.contains('groovy-binary')
    }
    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 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()
        }
    }

    groovypom.whenConfigured(removeJarjaredDependencies)

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

    // pom for "all" dependencies
    def allpom = pom('all', pomConfigureClosureWithoutTweaks)
    allpom.artifactId = 'groovy-all'
    allpom.whenConfigured { p ->
        // this is the only way to get a handle on `maven.Dependency`
        def dependencyClass = p.dependencies[0].getClass()
        p.dependencies.clear()
        // defer setting packaging until here otherwise gets overwritten
        p.packaging = 'pom'
        String groupId = project.group
        allprojects {
            if (it.name.startsWith('groovy') && !optionalModules.contains(it.name)) {
                def dep = dependencyClass.getDeclaredConstructor().newInstance()
                dep.groupId = groupId
                dep.artifactId = it.name
                dep.version = version
                p.dependencies.add(dep)
            }
        }
    }

    // bom for "all" dependencies
    def allbom = pom('bom', pomConfigureClosureWithoutTweaks)
    allbom.artifactId = 'groovy-bom'
    allbom.whenConfigured { p ->
        p.dependencies.clear()
        // defer setting packaging until here otherwise gets overwritten
        p.packaging = 'pom'
        p.withXml { xml ->
            def projectNode = xml.asNode()
            def dependencyManagement = projectNode.appendNode('dependencyManagement').appendNode('dependencies')
            String groupId = project.group
            allprojects { proj ->
                if (proj.name.startsWith('groovy')) {
                    dependencyManagement.appendNode('dependency').with { dep ->
                        dep.appendNode('groupId', groupId)
                        dep.appendNode('artifactId', proj.name)
                        dep.appendNode('version', proj.version)
                    }
                }
            }
        }
    }

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

install {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(modules()*.install)
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar, distBin, distDoc, dist, distBin])
    repositories {
        mavenInstaller pomAll
    }
    doFirst configureAdditionalArtifacts
}

uploadArchives {
    // make sure dependencies poms are built *before* the all pom
    dependsOn(modules()*.uploadArchives)
    dependsOn([sourceAllJar, javadocAllJar, groovydocAllJar, distBin, distDoc, dist, distBin])
    repositories {
        mavenDeployer pomAll
    }
    doFirst configureAdditionalArtifacts
}
