ext {
    jacoco_version = "0.8.8"
    coverageExcludes = [
            // data binding
            'android/databinding/**/*.class',
            '**/databinding/*Binding.class',
            '**/android/databinding/*Binding.class',
            '**/android/databinding/*',
            '**/androidx/databinding/*',
            '**/BR.*',
            // android
            '**/R.class',
            '**/R2*.*',
            '**/R2.class',
            '**/R2$*.class',
            '**/R$*.class',
            '**/BuildConfig.*',
            '**/Manifest*.*',
            '**/*Test*.*',
            'android/**/*.*',
            'androidx/**/*.*',
            'com/android/**/*.*',
            'com/google/**/*.*',
            // kotlin
            '**/*MapperImpl*.*',
            '**/*$ViewInjector*.*',
            '**/*$ViewBinder*.*',
            '**/*Component*.*',
            '**/*BR*.*',
            '**/*$Lambda$*.*',
            '**/*Companion*.*',
            '**/*Module*.*',
            '**/*Dagger*.*',
            '**/*Hilt*.*',
            '**/*Koin*.*',
            '**/*MembersInjector*.*',
            '**/*_MembersInjector.class',
            '**/*_Factory*.*',
            '**/*_Provide*Factory*.*',
            '**/*_ViewBinding*.*',
            //'**/*Extensions*.*',
            // sealed and data classes
            '**/*$Result.*',
            '**/*$Result$*.*',
            // adapters generated by moshi
            '**/*JsonAdapter.*',
            // others
            '**/AutoValue_*.*',
            '**/*Directions$*',
            '**/*Directions.*',
            '**/*JavascriptBridge.class',
            '**/*$InjectAdapter.class',
            '**/*$ModuleAdapter.class',
            '**/*Mock*.*', // Mock classes
    ]
}

buildscript.dependencies {
    classpath "org.jacoco:org.jacoco.core:$jacoco_version"
}

apply plugin: 'jacoco'

jacoco {
    toolVersion jacoco_version
}

project.afterEvaluate {

    tasks.create(name: "allDebugCoverage", type: JacocoReport) {
        group = "Reporting"
        description = "Generate overall Jacoco coverage report for the debug build."

        reports {
            html.enabled true
            xml.enabled true
        }

        def jClasses = subprojects.collect { proj ->
            "${proj.buildDir}/intermediates/javac/debug/classes"
        }
        def kClasses = subprojects.collect { proj ->
            "${proj.buildDir}/tmp/kotlin-classes/debug"
        }
        def javaClasses = jClasses.collect { path ->
            fileTree(dir: path, excludes: coverageExcludes)
        }
        def kotlinClasses = kClasses.collect { path ->
            fileTree(dir: path, excludes: coverageExcludes)
        }

        classDirectories.from = files([javaClasses, kotlinClasses])
        def sources = subprojects.collect { proj ->
            ["${proj.projectDir}/src/main/java", "${proj.projectDir}/src/main/kotlin",
             "${proj.projectDir}/src/debug/java", "${proj.projectDir}/src/debug/kotlin"]
        }.flatten()

        sourceDirectories.from = files(sources)

        def allReportFiles = project.fileTree("${projectDir}").include([
                "**/build/jacoco/*UnitTest.exec", // default path for the UnitTests report
                "**/build/outputs/code_coverage/**/*.ec", // default path for the UI Tests report
                "**/build/outputs/unit_test_code_coverage/**/*.exec", // path for the UnitTests report after enabling the testCoverageEnabled
        ])

        executionData.from = files(allReportFiles)
    }
}

afterEvaluate {
    subprojects.each { p ->
        allDebugCoverage.dependsOn "${p.name}:testDebugUnitTest"
        // We're adding only connectedDebugAndroidTest for local builds, because we can't run emulators in the pipeline for now.
        allDebugCoverage.dependsOn "${p.name}:connectedDebugAndroidTest"

    }
}

subprojects {
    apply plugin: 'jacoco'

    jacoco {
        toolVersion jacoco_version
    }

    afterEvaluate {
        tasks.create(name: "debugCoverage", type: JacocoReport, dependsOn: "testDebugUnitTest") {
            group = "Reporting"
            description = "This task is not creating the report. It is only creating the exec and ec files."
        }
        android {
            testOptions.unitTests {
                all {
                    jacoco {
                        includeNoLocationClasses true
                        excludes = ['jdk.internal.*']
                    }
                }
                returnDefaultValues = true
            }

            buildTypes.debug.testCoverageEnabled true
        }
    }

    // We need to force this resolution strategy because the UnitTest and UI Tests are not working well
    // because some dependency is using a different version of JaCoCo
    configurations.all {
        resolutionStrategy.eachDependency { details ->
            if ('org.jacoco' == details.requested.group) {
                details.useVersion jacoco_version
            }
        }
    }
}