plugins {
    id "com.android.application" apply false // Necessary for Android plugin to find its classes
    id "com.android.library" apply false
    id "com.google.osdetector" apply false
    id "me.champeau.gradle.japicmp" apply false
    id "net.ltgt.errorprone" apply false
}

import net.ltgt.gradle.errorprone.CheckSeverity
import org.gradle.util.GUtil

subprojects {
    apply plugin: "checkstyle"
    apply plugin: "idea"
    apply plugin: "signing"
    apply plugin: "jacoco"

    apply plugin: "com.google.osdetector"
    apply plugin: "net.ltgt.errorprone"

    group = "io.grpc"
    version = "1.48.0-SNAPSHOT" // CURRENT_GRPC_VERSION

    repositories {
        maven { // The google mirror is less flaky than mavenCentral()
            url "https://maven-central.storage-download.googleapis.com/maven2/" }
        mavenCentral()
        mavenLocal()
    }

    tasks.withType(JavaCompile) {
        it.options.compilerArgs += [
            "-Xlint:all",
            "-Xlint:-options",
            "-Xlint:-path",
            "-Xlint:-try"
        ]
        it.options.encoding = "UTF-8"
        if (rootProject.hasProperty('failOnWarnings') && rootProject.failOnWarnings.toBoolean()) {
            it.options.compilerArgs += ["-Werror"]
        }
    }

    tasks.withType(GenerateModuleMetadata) {
        // Module metadata, introduced in Gradle 6.0, conflicts with our publishing task for
        // grpc-alts and grpc-compiler.
        enabled = false
    }

    def isAndroid = project.name in [
            'grpc-android', 'grpc-android-interop-testing', 'grpc-cronet']

    ext {
        def exeSuffix = osdetector.os == 'windows' ? ".exe" : ""
        protocPluginBaseName = 'protoc-gen-grpc-java'
        javaPluginPath = "$rootDir/compiler/build/exe/java_plugin/$protocPluginBaseName$exeSuffix"

        configureProtoCompilation = {
            String generatedSourcePath = "${projectDir}/src/generated"
            project.protobuf {
                protoc {
                    if (project.hasProperty('protoc')) {
                        path = project.protoc
                    } else {
                        artifact = libs.protobuf.protoc.get()
                    }
                }
                generateProtoTasks {
                    all().each { task ->
                        // Recompile protos when build.gradle has been changed, because
                        // it's possible the version of protoc has been changed.
                        task.inputs.file "${rootProject.projectDir}/build.gradle"
                        if (isAndroid) {
                            task.builtins {
                                java { option 'lite' }
                            }
                        }
                    }
                }
            }
            if (rootProject.childProjects.containsKey('grpc-compiler')) {
                // Only when the codegen is built along with the project, will we be able to run
                // the grpc code generator.
                task syncGeneratedSources { }
                project.protobuf {
                    plugins { grpc { path = javaPluginPath } }
                    generateProtoTasks {
                        all().each { task ->
                            String variantOrSourceSet = isAndroid ? task.variant.name : task.sourceSet.name
                            def syncTask = project.tasks.register("syncGeneratedSources${variantOrSourceSet}", Sync) {
                                from "$buildDir/generated/source/proto/${variantOrSourceSet}/grpc"
                                into "$generatedSourcePath/${variantOrSourceSet}/grpc"
                                String source = GUtil.toCamelCase(variantOrSourceSet)
                                if (source == "Main") {
                                    source = ""
                                }
                                dependsOn "generate${source}Proto"
                            }
                            syncGeneratedSources.dependsOn syncTask

                            task.dependsOn ':grpc-compiler:java_pluginExecutable'
                            // Recompile protos when the codegen has been changed
                            task.inputs.file javaPluginPath
                            task.plugins { grpc { option 'noversion' } }
                            if (isAndroid) {
                                task.plugins {
                                    grpc {
                                        option 'lite'
                                    }
                                }
                            }
                        }
                    }
                }
                // Re-sync as part of a normal build, to avoid forgetting to run the sync
                assemble.dependsOn syncGeneratedSources
            } else {
                // Otherwise, we just use the checked-in generated code.
                if (isAndroid) {
                    project.android.sourceSets {
                        debug { java { srcDir "${generatedSourcePath}/debug/grpc" } }
                        release { java { srcDir "${generatedSourcePath}/release/grpc" } }
                    }
                } else {
                    project.sourceSets {
                        main { java { srcDir "${generatedSourcePath}/main/grpc" } }
                        test { java { srcDir "${generatedSourcePath}/test/grpc" } }
                    }
                }
            }

            tasks.withType(JavaCompile) {
                appendToProperty(
                    it.options.errorprone.excludedPaths,
                    ".*/src/generated/[^/]+/java/.*" +
                        "|.*/build/generated/source/proto/[^/]+/java/.*",
                    "|")
            }
        }

        libraries = libs

        appendToProperty = { Property<String> property, String value, String separator ->
            if (property.present) {
                property.set(property.get() + separator + value)
            } else {
                property.set(value)
            }
        }
    }

    // Disable JavaDoc doclint on Java 8. It's annoying.
    if (JavaVersion.current().isJava8Compatible()) {
        allprojects {
            tasks.withType(Javadoc) {
                options.addStringOption('Xdoclint:none', '-quiet')
            }
        }
    }

    checkstyle {
        configDirectory = file("$rootDir/buildscripts")
        toolVersion = libs.versions.checkstyle.get()
        ignoreFailures = false
        if (rootProject.hasProperty("checkstyle.ignoreFailures")) {
            ignoreFailures = rootProject.properties["checkstyle.ignoreFailures"].toBoolean()
        }
    }

    if (!project.hasProperty('errorProne') || errorProne.toBoolean()) {
        dependencies {
            errorprone libs.errorprone.core
            errorproneJavac libs.errorprone.javac
        }
    } else {
        // Disable Error Prone
        tasks.withType(JavaCompile) {
            options.errorprone.enabled = false
        }
    }

    plugins.withId("java") {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8

        dependencies {
            testImplementation libraries.junit,
                    libraries.mockito.core,
                    libraries.truth
        }

        compileTestJava {
            // serialVersionUID is basically guaranteed to be useless in our tests
            options.compilerArgs += [
                "-Xlint:-serial"
            ]
        }

        jar.manifest {
            attributes('Implementation-Title': name,
            'Implementation-Version': version)
        }

        javadoc.options {
            encoding = 'UTF-8'
            use = true
            links 'https://docs.oracle.com/javase/8/docs/api/'
            source = "8"
        }

        checkstyleMain {
            source = fileTree(dir: "$projectDir/src/main", include: "**/*.java")
        }

        checkstyleTest {
            source = fileTree(dir: "$projectDir/src/test", include: "**/*.java")
        }

        // At a test failure, log the stack trace to the console so that we don't
        // have to open the HTML in a browser.
        test {
            testLogging {
                exceptionFormat = 'full'
                showExceptions true
                showCauses true
                showStackTraces true
            }
            maxHeapSize = '1500m'
        }

        if (!project.hasProperty('errorProne') || errorProne.toBoolean()) {
            dependencies {
                annotationProcessor libs.guava.betaChecker
            }
        }

        compileJava {
            // This project targets Java 7 (no method references)
            options.errorprone.check("UnnecessaryAnonymousClass", CheckSeverity.OFF)
            // This project targets Java 7 (no time.Duration class)
            options.errorprone.check("PreferJavaTimeOverload", CheckSeverity.OFF)
            options.errorprone.check("JavaUtilDate", CheckSeverity.OFF)
            // The warning fails to provide a source location
            options.errorprone.check("MissingSummary", CheckSeverity.OFF)
        }
        compileTestJava {
            // LinkedList doesn't hurt much in tests and has lots of usages
            options.errorprone.check("JdkObsolete", CheckSeverity.OFF)
            options.errorprone.check("UnnecessaryAnonymousClass", CheckSeverity.OFF)
            options.errorprone.check("PreferJavaTimeOverload", CheckSeverity.OFF)
            options.errorprone.check("JavaUtilDate", CheckSeverity.OFF)
        }

        plugins.withId("ru.vyarus.animalsniffer") {
	    // Only available after java plugin has loaded
            animalsniffer {
                toolVersion = libs.versions.animalsniffer.get()
            }
        }
    }

    plugins.withId("java-library") {
        // Detect Maven Enforcer's dependencyConvergence failures. We only care
        // for artifacts used as libraries by others with Maven.
        tasks.register('checkUpperBoundDeps') {
            doLast {
                requireUpperBoundDepsMatch(configurations.runtimeClasspath, project)
            }
        }
        tasks.named('compileJava') {
            dependsOn checkUpperBoundDeps
        }
    }

    plugins.withId("me.champeau.jmh") {
        // invoke jmh on a single benchmark class like so:
        //   ./gradlew -PjmhIncludeSingleClass=StatsTraceContextBenchmark clean :grpc-core:jmh
	compileJmhJava {
	    sourceCompatibility = 1.8
	    targetCompatibility = 1.8
	}
        jmh {
            warmupIterations = 10
            iterations = 10
            fork = 1
            // None of our benchmarks need the tests, and we have pseudo-circular
            // dependencies that break when including them. (context's testCompile
            // depends on core; core's testCompile depends on testing)
            includeTests = false
            if (project.hasProperty('jmhIncludeSingleClass')) {
                include = [
                    project.property('jmhIncludeSingleClass')
                ]
            }
        }
    }

    plugins.withId("com.github.johnrengelman.shadow") {
        tasks.named("shadowJar") {
            // Do a dance to remove Class-Path. This needs to run after the doFirst() from the
            // shadow plugin that adds Class-Path and before the core jar action. Using doFirst will
            // have this run before the shadow plugin, and doLast will run after the core jar
            // action. See #8606.
            // The shadow plugin adds another doFirst when application is used for setting
            // Main-Class. Ordering with it doesn't matter.
            actions.add(plugins.hasPlugin("application") ? 2 : 1, new Action<Task>() {
                @Override public void execute(Task task) {
                    if (!task.manifest.attributes.remove("Class-Path")) {
                        throw new AssertionError("Did not find Class-Path to remove from manifest")
                    }
                }
            })
        }
    }

    plugins.withId("maven-publish") {
        publishing {
            publications {
                // do not use mavenJava, as java plugin will modify it via "magic"
                maven(MavenPublication) {
                    pom {
                        name = project.group + ":" + project.name
                        url = 'https://github.com/grpc/grpc-java'
                        afterEvaluate {
                            // description is not available until evaluated.
                            description = project.description
                        }

                        scm {
                            connection = 'scm:git:https://github.com/grpc/grpc-java.git'
                            developerConnection = 'scm:git:git@github.com:grpc/grpc-java.git'
                            url = 'https://github.com/grpc/grpc-java'
                        }

                        licenses {
                            license {
                                name = 'Apache 2.0'
                                url = 'https://opensource.org/licenses/Apache-2.0'
                            }
                        }

                        developers {
                            developer {
                                id = "grpc.io"
                                name = "gRPC Contributors"
                                email = "grpc-io@googlegroups.com"
                                url = "https://grpc.io/"
                                organization = "gRPC Authors"
                                organizationUrl = "https://www.google.com"
                            }
                        }

                        withXml {
                            if (!(project.name in
                            [
                                "grpc-stub",
                                "grpc-protobuf",
                                "grpc-protobuf-lite",
                            ])) {
                                asNode().dependencies.'*'.findAll() { dep ->
                                    dep.artifactId.text() in ['grpc-api', 'grpc-core']
                                }.each() { core ->
                                    core.version*.value = "[" + core.version.text() + "]"
                                }
                            }
                        }
                    }
                }
            }
            repositories {
                maven {
                    if (rootProject.hasProperty('repositoryDir')) {
                        url = new File(rootProject.repositoryDir).toURI()
                    } else {
                        String stagingUrl
                        if (rootProject.hasProperty('repositoryId')) {
                            stagingUrl = 'https://oss.sonatype.org/service/local/staging/deployByRepositoryId/' +
                                    rootProject.repositoryId
                        } else {
                            stagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
                        }
                        credentials {
                            if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) {
                                username = rootProject.ossrhUsername
                                password = rootProject.ossrhPassword
                            }
                        }
                        def releaseUrl = stagingUrl
                        def snapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
                        url = version.endsWith('SNAPSHOT') ? snapshotUrl : releaseUrl
                    }
                }
            }
        }

        signing {
            required false
            sign publishing.publications.maven
        }

        plugins.withId("java") {
            java {
                withJavadocJar()
                withSourcesJar()
            }

            publishing {
                publications {
                    maven {
                        if (project.name != 'grpc-netty-shaded') {
                            from components.java
                        }
                    }
                }
            }
        }
    }

    // Run with: ./gradlew japicmp --continue
    plugins.withId("me.champeau.gradle.japicmp") {
        def baselineGrpcVersion = '1.6.1'

        // Get the baseline version's jar for this subproject
        File baselineArtifact = null
        // Use a detached configuration, otherwise the current version's jar will take precedence
        // over the baseline jar.
        // A necessary hack, the intuitive thing does NOT work:
        // https://discuss.gradle.org/t/is-the-default-configuration-leaking-into-independent-configurations/2088/6
        def oldGroup = project.group
        try {
            project.group = 'virtual_group_for_japicmp'
            String depModule = "io.grpc:${project.name}:${baselineGrpcVersion}@jar"
            String depJar = "${project.name}-${baselineGrpcVersion}.jar"
            Configuration configuration = configurations.detachedConfiguration(
                    dependencies.create(depModule)
                    )
            baselineArtifact = files(configuration.files).filter {
                it.name.equals(depJar)
            }.singleFile
        } finally {
            project.group = oldGroup
        }

        // Add a japicmp task that compares the current .jar with baseline .jar
        task japicmp(type: me.champeau.gradle.japicmp.JapicmpTask, dependsOn: jar) {
            oldClasspath = files(baselineArtifact)
            newClasspath = files(jar.archivePath)
            onlyBinaryIncompatibleModified = false
            // Be quiet about things that did not change
            onlyModified = true
            // This task should fail if there are incompatible changes
            failOnModification = true
            ignoreMissingClasses = true
            htmlOutputFile = file("$buildDir/reports/japi.html")

            packageExcludes = ['io.grpc.internal']

            // Also break on source incompatible changes, not just binary.
            // Eg adding abstract method to public class.
            // TODO(zpencer): enable after japicmp-gradle-plugin/pull/14
            // breakOnSourceIncompatibility = true

            // Ignore any classes or methods marked @ExperimentalApi
            // TODO(zpencer): enable after japicmp-gradle-plugin/pull/15
            // annotationExcludes = ['@io.grpc.ExperimentalApi']
        }
    }
}

class DepAndParents {
    DependencyResult dep
    List<String> parents
}

/**
 * Make sure that Maven would select the same versions as Gradle selected.
 * This is essentially the same as if we used Maven Enforcer's
 * requireUpperBoundDeps for our artifacts.
 */
def requireUpperBoundDepsMatch(Configuration conf, Project project) {
    // artifact name => version
    Map<String,String> golden = conf.resolvedConfiguration.resolvedArtifacts.collectEntries {
        ResolvedArtifact it ->
            ModuleVersionIdentifier id = it.moduleVersion.id
            [id.group + ":" + id.name, id.version]
    }
    // Breadth-first search like Maven for dependency resolution
    Queue<DepAndParents> queue = new ArrayDeque<>()
    conf.incoming.resolutionResult.root.dependencies.each {
        queue.add(new DepAndParents(dep: it, parents: [project.displayName]))
    }
    Set<String> found = new HashSet<>()
    while (!queue.isEmpty()) {
        DepAndParents depAndParents = queue.remove()
        ResolvedDependencyResult result = (ResolvedDependencyResult) depAndParents.dep
        ModuleVersionIdentifier id = result.selected.moduleVersion
        String artifact = id.group + ":" + id.name
        if (found.contains(artifact))
            continue
        found.add(artifact)
        String version
        if (result.requested instanceof ProjectComponentSelector) {
            ProjectComponentSelector selector = (ProjectComponentSelector) result.requested
            version = project.findProject(selector.projectPath).version
        } else {
            version = ((ModuleComponentSelector) result.requested).version
        }
        String goldenVersion = golden[artifact]
        if (goldenVersion != version && "[$goldenVersion]" != version) {
            throw new RuntimeException(
                "Maven version skew: $artifact ($version != $goldenVersion) "
                + "Bad version dependency path: " + depAndParents.parents
                + " Run './gradlew $project.path:dependencies --configuration $conf.name' "
                + "to diagnose")
        }
        result.selected.dependencies.each {
            queue.add(new DepAndParents(
                dep: it, parents: depAndParents.parents + [artifact + ":" + version]))
        }
    }
}
