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
    id 'com.google.cloud.tools.jib' 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.49.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).configureEach {
        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).configureEach {
        // 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.
                def syncGeneratedSources = tasks.register("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.configure {
                                dependsOn syncTask
                            }

                            task.configure {
                                dependsOn ':grpc-compiler:java_pluginExecutable'
                                // Recompile protos when the codegen has been changed
                                inputs.file javaPluginPath
                                plugins { grpc { option 'noversion' } }
                                if (isAndroid) {
                                    plugins {
                                        grpc {
                                            option 'lite'
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // Re-sync as part of a normal build, to avoid forgetting to run the sync
                tasks.named("assemble").configure {
                    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.each() { sourceSet ->
                        sourceSet.java { srcDir "${generatedSourcePath}/${sourceSet.name}/grpc" }
                    }
                }
            }

            tasks.withType(JavaCompile).configureEach {
                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).configureEach {
                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).configureEach {
            options.errorprone.enabled = false
        }
    }

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

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

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

        tasks.named("jar").configure {
            manifest {
                attributes('Implementation-Title': name,
                        'Implementation-Version': project.version)
            }
        }

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

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

        tasks.named("checkstyleTest").configure {
            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.
        tasks.named("test").configure {
            testLogging {
                exceptionFormat = 'full'
                showExceptions true
                showCauses true
                showStackTraces true
            }
            maxHeapSize = '1500m'
        }

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

        tasks.named("compileJava").configure {
            // 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)
        }
        tasks.named("compileTestJava").configure {
            // 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').configure {
            dependsOn checkUpperBoundDeps
        }
    }

    plugins.withId("me.champeau.jmh") {
        // invoke jmh on a single benchmark class like so:
        //   ./gradlew -PjmhIncludeSingleClass=StatsTraceContextBenchmark clean :grpc-core:jmh
	tasks.named("compileJmhJava").configure {
	    sourceCompatibility = 1.8
	    targetCompatibility = 1.8
	}
        tasks.named("jmh").configure {
            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").configure {
            // 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
        tasks.register("japicmp", 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]))
        }
    }
}
