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

// Workaround needed for nexus publishing bug
// version and group must be specified in the root project
// https://github.com/gradle-nexus/publish-plugin/issues/310
version = projectVersion
group = 'this.will.be.overridden'

def publishedProjects = [
        'grails-async',
        'grails-async-core',
        'grails-async-gpars',
        'grails-async-rxjava',
        'grails-async-rxjava2',
        'grails-async-rxjava3',
        'grails-bom',
        'grails-bootstrap',
        'grails-cache',
        'grails-codecs',
        'grails-codecs-core',
        'grails-common',
        'grails-console',
        'grails-controllers',
        'grails-converters',
        'grails-core',
        'grails-databinding',
        'grails-databinding-core',
        'grails-datasource',
        'grails-dependencies-assets',
        'grails-dependencies-starter-web',
        'grails-dependencies-test',
        'grails-domain-class',
        'grails-encoder',
        'grails-events',
        'grails-events-compat',
        'grails-events-core',
        'grails-events-gpars',
        'grails-events-rxjava',
        'grails-events-rxjava2',
        'grails-events-rxjava3',
        'grails-events-spring',
        'grails-events-transforms',
        'grails-fields',
        'grails-geb',
        'grails-gsp',
        'grails-gsp-core',
        'grails-i18n',
        'grails-interceptors',
        'grails-layout',
        'grails-logging',
        'grails-micronaut',
        'grails-mimetypes',
        'grails-rest-transforms',
        'grails-scaffolding',
        'grails-services',
        'grails-shell-cli',
        'grails-sitemesh3',
        'grails-spring',
        'grails-taglib',
        'grails-test-core',
        'grails-testing-support-core',
        'grails-testing-support-mongodb',
        'grails-testing-support-views-gson',
        'grails-testing-support-web',
        'grails-url-mappings',
        'grails-validation',
        'grails-views-core',
        'grails-views-gson',
        'grails-views-markup',
        'grails-web-boot',
        'grails-web-common',
        'grails-web-core',
        'grails-web-databinding',
        'grails-web-gsp',
        'grails-web-gsp-taglib',
        'grails-web-jsp',
        'grails-web-mvc',
        'grails-web-taglib',
        'grails-web-url-mappings',
        // datastore
        'grails-datamapping-async',
        'grails-datamapping-core',
        'grails-datamapping-core-test',
        'grails-datastore-async',
        'grails-datastore-core',
        //'grails-datamapping-rx',
        'grails-datamapping-support',
        'grails-datamapping-tck',
        'grails-datamapping-validation',
        'grails-datastore-web',
        'grails-testing-support-datamapping',
        // simple
        'grails-data-simple',
        // hibernate5
        'grails-data-hibernate5',
        'grails-data-hibernate5-core',
        'grails-data-hibernate5-dbmigration',
        'grails-data-hibernate5-spring-boot',
        // mongodb
        'grails-data-mongodb',
        'grails-data-mongodb-bson',
        'grails-data-mongodb-core',
        'grails-data-mongodb-ext',
        'grails-data-mongodb-gson-templates',
        'grails-data-mongodb-spring-boot',
        // wrapper
        'grails-wrapper',
        // profiles
        'grails-profiles-base',
        'grails-profiles-plugin',
        'grails-profiles-profile',
        'grails-profiles-rest-api',
        'grails-profiles-rest-api-plugin',
        'grails-profiles-web',
        'grails-profiles-web-plugin',
]

subprojects {
    if (name in publishedProjects) {
        // This has to be applied here in the root project due to the nexus plugin requirements
        if (name.startsWith('grails-profiles')) {
            apply plugin: 'org.apache.grails.gradle.grails-publish-profile'
        } else {
            apply plugin: 'org.apache.grails.gradle.grails-publish'
        }
    }
}

// subprojects will register dependencies via the publish plugin
tasks.register('publishAllPublicationsToTestCaseMavenRepoRepository')

def aggregatePublishedArtifacts = tasks.register('aggregatePublishedArtifacts')

tasks.register('aggregateChecksums').configure {
    group = 'publishing'
    description = 'Aggregates all SHA-256 checksums from subprojects into a single file.'

    def outputFileProvider = rootProject.layout.buildDirectory.file('grails-core-checksums.txt')
    outputs.file(outputFileProvider)

    dependsOn(
            subprojects
                    .findResults { it.tasks.names.contains('publishedChecksums') ? "${it.path}:publishedChecksums" : null }
    )
    finalizedBy(aggregatePublishedArtifacts)

    outputs.upToDateWhen { false } // not worth caching

    doLast {
        def outputFile = outputFileProvider.get().asFile
        outputFile.withPrintWriter { writer ->
            subprojects.each { sub ->
                def checksumDir = sub.layout.buildDirectory.dir('checksums').get().asFile
                if (checksumDir.exists()) {
                    checksumDir.eachFileMatch(~/.*\.sha512/) {
                        def jarName = it.name - '.sha512'
                        def checksumLine = it.text.trim()
                        def checksum = checksumLine.tokenize().first()
                        writer.println("$jarName $checksum")
                    }
                }
            }
        }

        println "Checksum manifest written to ${outputFile}"
    }
}

aggregatePublishedArtifacts.configure {
    group = 'publishing'
    description = 'Aggregates all published artifacts from subprojects into a single file.'

    def outputFileProvider = rootProject.layout.buildDirectory.file('grails-core-artifacts.txt')
    outputs.file(outputFileProvider)

    outputs.upToDateWhen { false } // not worth caching

    dependsOn(subprojects.findResults { it.tasks.names.contains('savePublishedArtifacts') ? "${it.path}:savePublishedArtifacts" : null })

    doLast {
        def outputFile = outputFileProvider.get().asFile
        outputFile.text = '' // clear previous
        outputFile.withPrintWriter { writer ->
            subprojects.each { sub ->
                def artifactsDir = sub.layout.buildDirectory.dir('artifacts').get().asFile
                if (artifactsDir.exists()) {
                    artifactsDir.eachFileMatch(~/.*\.txt/) {
                        def artifactName = it.name - '.txt'
                        def coordinates = it.text.trim()
                        writer.println("$artifactName $coordinates")
                    }
                }
            }
        }

        println "Published artifacts written to ${outputFile}"
    }
}