// cannot reference the plugins declared in the version catalogs here because it requires the use of the `plugins` block instead of the `apply plugin` command
// the `plugins` block cannot be used in gradle files such as this one, which are imported into other gradle files with the `apply from` command
apply plugin: 'jacoco'

if (project.hasProperty('android')) {
    android.buildTypes {
        debug {
            testCoverageEnabled = true
        }
    }
}

project.afterEvaluate {
    jacoco {
        toolVersion = "${libs.versions.jacoco}"
    }

    tasks.withType(Test).configureEach {
        jacoco {
            excludes += coverageExclusions
            includeNoLocationClasses = true
        }
    }

    if (project.hasProperty('android')) {
        android.buildTypes.every { buildType ->
            def buildTypeName = buildType.name.capitalize()

            tasks.register("jacoco${buildTypeName}TestReport", JacocoReport) {
                group 'Reporting'
                description "Generate JaCoCo report for ${buildTypeName} tests"
                dependsOn "test${buildTypeName}UnitTest"

                reports {
                    xml.required = true
                    html.required = false
                    csv.required = false
                }

                additionalSourceDirs(files([
                    android.sourceSets.main.java.srcDirs,
                    android.sourceSets.debug.java.srcDirs
                ]))
                additionalClassDirs(files([
                    fileTree(dir: "${layout.buildDirectory.get().asFile}/intermediates/javac/${buildType.name}", excludes: coverageExclusions),
                    fileTree(dir: "${layout.buildDirectory.get().asFile}/tmp/kotlin-classes/${buildType.name}", excludes: coverageExclusions)
                ]))
                executionData(
                    fileTree(dir: "${layout.buildDirectory.get().asFile}", includes: [
                        "outputs/unit_test_code_coverage/${buildType.name}UnitTest/test${buildTypeName}UnitTest.exec",
                        "jacoco/test${buildTypeName}UnitTest.exec",
                        "outputs/code-coverage/connected/*coverage.ec"
                    ])
                )

            }
        }
    }
}

ext.coverageExclusions = [
    // Android
    '**/BuildConfig.*',
    '**/Manifest*.*',
    '**/R$*.class',
    '**/R.class',

    // Data binding
    '**/*BindingAdapter.*',
    '**/*BindingAdapters.*',
    '**/*ViewBinding.*',
    '**/BR$*.class',
    '**/BR.class',
    '**/DataBinderMapperImpl*.*',
    '**/DataBinderMapperImpl.*',
    '**/databinding/**',

    // Activities, Fragments, etc. (not tested with unit tests)
    '**/*Activity$*.*',
    '**/*Activity.*',
    '**/*Adapter$*.*',
    '**/*Adapter.*',
    '**/*Behavior.*',
    '**/*Dialog.*',
    '**/*Drawable.*',
    '**/*Fragment$*.*',
    '**/*Fragment.*',
    '**/*View$*.*',
    '**/*View.*',
    '**/*ViewHolder$*.*',
    '**/*ViewHolder.*',

    // Parcelize
    '**/*$Creator',
    '**/*$Creator*.*',

    // Activity result contract
    '**/*ActivityResults.*',
    '**/*ResultContract.*',

    // Dagger + Hilt
    '**/*_ComponentTreeDeps.*',
    '**/*_Factory.*',
    '**/*_GeneratedInjector.*',
    '**/*_HiltComponents.*',
    '**/*_HiltComponents_*.*',
    '**/*_HiltModules*.*',
    '**/*_HiltModules.*',
    '**/*_HiltModules_*.*',
    '**/*_Member*Injector.*',
    '**/*_Provide*Factory*.*',
    '**/*_Provide*Factory.*',
    '**/*_ProvideFactory.*',
    '**/Dagger*.*',
    '**/Hilt_*.*',
    '**/dagger/**',
    '**/hilt_aggregated_deps/**',

    // Test classes
    '**/*Test.*',
    '**/Test*.*',

    // Fix issue with JaCoCo on JDK
    'jdk.internal.*',

    // Custom views not following *View naming
    '**/AddressFormInput*.*',
    '**/AdyenSwipeToRevealLayout*.*',
    '**/AdyenTextInputEditText*.*',
    '**/CardNumberInput.*',
    '**/DefaultPayButton.*',
    '**/ExpiryDateInput.*',
    '**/GiftCardNumberInput.*',
    '**/IbanInput.*',
    '**/PayButton.*',
    '**/SecurityCodeInput.*',
    '**/SocialSecurityNumberInput.*',

    // Project specific files that can't be unit tested
    '**/*ComponentProvider$*.*',
    '**/*ComponentProvider.*',
    '**/*DropInService$*.*',
    '**/*DropInService.*',
    '**/*Factory.*',
    '**/*ViewProvider.*',
    '**/AdyenLogKt*',
    '**/BuildUtils.*',
    '**/CheckCompileOnlyKt*',
    '**/ComposeExtensions*.*',
    '**/ContextExtensions*.*',
    '**/DropIn$*.*',
    '**/DropIn.*',
    '**/DropInExt*.*',
    '**/FileDownloader*.*',
    '**/FragmentExtensions*.*',
    '**/FragmentProvider$*.*',
    '**/FragmentProvider.*',
    '**/ImageLoadingExtensions*.*',
    '**/ImageLoadingExtensions.*',
    '**/ImageSaver.*',
    '**/InstallmentFilter.*',
    '**/LazyArguments*.*',
    '**/LifecycleExtensions*.*',
    '**/LogcatLogger.*',
    '**/PdfOpener.*',
    '**/ResultExtKt*',
    '**/RunCompileOnlyKt*',
    '**/ViewExtensions*.*',
    '**/ViewModelExt*.*',

    // Example app and test-core are not applicable
    'com/adyen/checkout/example/**',
    'com/adyen/checkout/test/**'
]
