ext.coverageModules = [
        'stream-chat-android-client',
        'stream-chat-android-compose',
        'stream-chat-android-core',
        'stream-chat-android-markdown-transformer',
        'stream-chat-android-offline',
        'stream-chat-android-state',
        'stream-chat-android-ui-common',
        'stream-chat-android-ui-utils'
]

ext.koverClassExcludes = [
        '*R',
        '*R$*',
        '*BuildConfig',
        '*Manifest*',
        '*Composable*'
]
ext.koverAnnotationExcludes = [
        'androidx.compose.ui.tooling.preview.Preview'
]

def configureKoverReports(project) {
    project.kover {
        reports {
            verify {
                warningInsteadOfFailure = true
            }
            filters {
                excludes {
                    classes(rootProject.ext.koverClassExcludes as String[])
                    annotatedBy(rootProject.ext.koverAnnotationExcludes as String[])
                }
            }
        }
    }
}

def coverageModulesWithTests = subprojects.findAll {
    rootProject.ext.coverageModules.contains(it.name) && file("${it.projectDir}/src/test").exists()
}
println("\nSetting up coverage for:\n${coverageModulesWithTests.join("\n")}\n")

// Configure code coverage for modules with tests
subprojects {
    def isCoverageModule = coverageModulesWithTests.collect {it.name}.contains(name)

    sonar {
        skipProject = !isCoverageModule
    }

    if (isCoverageModule) {
        apply plugin: "org.jetbrains.kotlinx.kover"

        afterEvaluate {
            def isAndroidModule = plugins.hasPlugin("com.android.library") || plugins.hasPlugin("com.android.application")
            def hasPaparazziPlugin = plugins.hasPlugin("app.cash.paparazzi")

            if (isAndroidModule) {
                android {
                    buildTypes {
                        debug {
                            testCoverageEnabled = true
                            enableUnitTestCoverage = true
                        }
                    }
                }
            }

            // Determine the appropriate test task name based on module type and plugins
            def testTaskName = isAndroidModule
                    ? (hasPaparazziPlugin ? "verifyPaparazziDebug" : "testDebugUnitTest")
                    : "test"

            tasks.register("testCoverage") {
                group = "verification"
                description = "Run module-specific tests"
                dependsOn(testTaskName)
            }

            kover {
                currentProject {
                    // Variant configuration for aggregated coverage
                    createVariant("coverage") {
                        if (isAndroidModule) {
                            add(["debug"], true)
                        } else {
                            add(["jvm"], true)
                        }
                    }
                }
                configureKoverReports(project)
            }
        }
    }
}

// Configure root project to aggregate coverage reports
apply plugin: "org.jetbrains.kotlinx.kover"

// Specify the projects that should be included in the aggregate coverage report
coverageModulesWithTests.each { project -> dependencies { kover(project) } }

// Aggregate all submodules' testCoverage + merged reports
tasks.register("testCoverage") {
    group = "verification"
    description = "Run all tests in all modules and generate merged coverage report"

    // Run Paparazzi tests of the UI Components module but do not include its coverage in the report
    // until we can update Paparazzi and Kover libraries alongside Kotlin and Compose.
    // See https://linear.app/stream/issue/AND-819/update-paparazzi-and-kover-libraries
    dependsOn("stream-chat-android-ui-components:verifyPaparazziDebug")

    dependsOn coverageModulesWithTests.collect { ":${it.name}:testCoverage" }

    finalizedBy("koverXmlReportCoverage", "koverHtmlReportCoverage")
}

kover {
    currentProject {
        // Variant configuration for aggregated coverage (needs to be defined in the root project too)
        createVariant("coverage") {}
    }
    configureKoverReports(project)
}

sonar {
    properties {
        property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/kover/reportCoverage.xml"
    }
}
