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') {
            inputs.files(configurations.runtimeClasspath).withNormalizer(ClasspathNormalizer)
            outputs.file("${buildDir}/tmp/${name}") // Fake output for UP-TO-DATE checking
            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]))
        }
    }
}
