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

if (rootProject.hasProperty('coverage') && Boolean.valueOf(rootProject.getProperty('coverage'))) {
    // we only apply the jacoco configuration if a system property is set, in order to avoid instrumentation if we
    // are not specifically asking for code coverage

    allprojects {
        if (!['performance', 'binary-compatibility'].contains(it.name)) {
            apply plugin: 'jacoco'
        }

        project.afterEvaluate {
            tasks.withType(JacocoReport) {
                if (name != 'jacocoAllReport' && name != 'jacocoAllIndyReport') {
                    sourceDirectories += files(project.sourceSets.main.allGroovy.srcDirs)
//                    classDirectories += files(project.sourceSets.main.output)
                }
            }
        }
    }

    // To avoid "Can't add different class with same name" fatal error
    // due to different classes generated when using Indy, create two reports
    // No need to include Java class directories since Groovy one includes those classes

    task jacocoMerge(type: JacocoMerge) {
        destinationFile = file("$buildDir/jacoco/jacoco-all.exec")
        allprojects {
            project.plugins.withType(JavaPlugin) {
                project.tasks.withType(Test) { task ->
                    if (sourceSets.test.allSource.srcDirs.any { it.exists() } && !task.name.contains('Indy')) {
                        executionData(task)
                    }
                }
            }
        }
    }

    task jacocoMergeIndy(type: JacocoMerge) {
        destinationFile = file("$buildDir/jacoco/jacoco-all-indy.exec")
        allprojects {
            project.plugins.withType(JavaPlugin) {
                project.tasks.withType(Test) { task ->
                    if (sourceSets.test.allSource.srcDirs.any { it.exists() } && task.name.contains('Indy')) {
                        executionData(task)
                    }
                }
            }
        }
    }

    task jacocoAllReport(type: JacocoReport, dependsOn: 'jacocoMerge') {
        executionData jacocoMerge.destinationFile
        allprojects {
            project.plugins.withType(JavaPlugin) {
                def sd = sourceDirectories ?: files()
                def cd = classDirectories ?: files()
                sourceDirectories = sd + files(project.sourceSets.main.allGroovy.srcDirs, project.sourceSets.main.allJava.srcDirs)
                classDirectories = cd + files(compileGroovy.destinationDir)
            }
        }
    }

    task jacocoAllIndyReport(type: JacocoReport, dependsOn: 'jacocoMergeIndy') {
        executionData jacocoMergeIndy.destinationFile
        allprojects {
            project.plugins.withType(JavaPlugin) {
                def sd = sourceDirectories ?: files()
                def cd = classDirectories ?: files()
                sourceDirectories = sd + files(project.sourceSets.main.allGroovy.srcDirs, project.sourceSets.main.allJava.srcDirs)
                classDirectories = cd + files(compileGroovyWithIndy.destinationDir)
            }
        }
    }

    check.dependsOn jacocoAllReport
    check.dependsOn jacocoAllIndyReport
}
