/*
 *  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') {
                    sourceDirectories.from = sourceDirectories.from + files(project.sourceSets.main.allGroovy.srcDirs)
//                    classDirectories += files(project.sourceSets.main.output)
                }
            }
        }
    }

    // To avoid "Can't add different class with same name" fatal error
    // 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() }) {
                        executionData(task)
                    }
                }
            }
        }

        executionData = files(executionData).filter { f -> f.exists() }
    }

    task jacocoAllReport(type: JacocoReport, dependsOn: 'jacocoMerge') {
        executionData jacocoMerge.destinationFile
        reports {
            xml {
                enabled true
            }
            html {
                enabled true
            }
        }

        allprojects {
            project.plugins.withType(JavaPlugin) {
                def sd = sourceDirectories.from ?: files()
                def cd = classDirectories.from ?: files()
                sourceDirectories.from = sd + files(project.sourceSets.main.allGroovy.srcDirs, project.sourceSets.main.allJava.srcDirs)
                classDirectories.from = cd + files(compileGroovy.destinationDir)
            }
        }
    }

    check.dependsOn jacocoAllReport
    tasks.sonarqube.dependsOn jacocoAllReport
}
