// Merge of
// https://github.com/mgouline/android-samples/blob/master/jacoco/app/build.gradle
// and https://github.com/pushtorefresh/storio/blob/master/gradle/jacoco-android.gradle

// Requires Jacoco plugin in build classpath.
apply plugin: 'jacoco'

// Enables code coverage for JVM tests.
// Android Gradle Plugin out of the box supports only code coverage for instrumentation tests.
project.afterEvaluate {
    // Grab all build types and product flavors
    def buildTypes = android.buildTypes.collect { type -> type.name }
    def productFlavors = android.productFlavors.collect { flavor -> flavor.name }

    // When no product flavors defined, use empty
    if (!productFlavors) productFlavors.add('')

    productFlavors.each { productFlavorName ->
        buildTypes.each { buildTypeName ->
            def sourceName, sourcePath
            if (!productFlavorName) {
                sourceName = sourcePath = "${buildTypeName}"
            } else {
                sourceName = "${productFlavorName}${buildTypeName.capitalize()}"
                sourcePath = "${productFlavorName}/${buildTypeName}"
            }
            def testTaskName = "test${sourceName.capitalize()}UnitTest"
            def coverageTaskName = "${testTaskName}Coverage"

            // Create coverage task of form 'testFlavorTypeUnitTestCoverage' depending on 'testFlavorTypeUnitTest'
            task "${coverageTaskName}"(type: JacocoReport, dependsOn: "$testTaskName") {
                group = 'Reporting'
                description = "Generate Jacoco coverage reports for the ${sourceName.capitalize()} build."

                classDirectories = fileTree(
                        dir: "${project.buildDir}/intermediates/classes/${sourcePath}",
                        excludes: ['**/R.class',
                                   '**/R$*.class',
                                   '**/*$ViewInjector*.*',
                                   '**/*$ViewBinder*.*',
                                   '**/BuildConfig.*',
                                   '**/Manifest*.*',
                                   '**/*$Lambda$*.*', // Jacoco can not handle several "$" in class name.
                                   '**/*$inlined$*.*', // Kotlin specific, Jacoco can not handle several "$" in class name.
                                   '**/*Module.*', // Modules for Dagger.
                                   '**/*Dagger*.*', // Dagger auto-generated code.
                                   '**/*MembersInjector*.*', // Dagger auto-generated code.
                                   '**/*_Provide*Factory*.*'] // Dagger auto-generated code.
                )

                def coverageSourceDirs = [
                        'src/main/java',
                        "src/$productFlavorName/java",
                        "src/$buildTypeName/java"
                ]

                additionalSourceDirs = files(coverageSourceDirs)
                sourceDirectories = files(coverageSourceDirs)
                executionData = files("${project.buildDir}/jacoco/${testTaskName}.exec")

                reports {
                    xml.enabled = true
                    html.enabled = true
                }
            }

            build.dependsOn "${coverageTaskName}"
        }
    }
}
