plugins {
    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.55.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")
                          .withPathSensitivity(PathSensitivity.RELATIVE)
                          .withPropertyName('root 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 JavaVersion.current().isJava11Compatible() ? libs.errorprone.core : libs.errorprone.corejava8
        }
    } 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 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("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')) {
                includes = [
                    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]))
        }
    }
}
