/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

plugins { id 'org.apache.beam.module' }

// Set a specific version of 'com.google.apis:google-api-services-dataflow'
// by adding -Pdataflow.version=<version> in Gradle command. Otherwise,
// 'google_clients_version' defined in BeamModulePlugin will be used as default.
def DATAFLOW_VERSION = "dataflow.version"

// Get full dependency of 'com.google.apis:google-api-services-dataflow'
def google_api_services_dataflow = project.hasProperty(DATAFLOW_VERSION) ? "com.google.apis:google-api-services-dataflow:" + getProperty(DATAFLOW_VERSION) : library.java.google_api_services_dataflow

// Returns a string representing the relocated path to be used with the shadow
// plugin when given a suffix such as "com.".
def getWorkerRelocatedPath = { String suffix ->
    return ("org.apache.beam.runners.dataflow.worker.repackaged."
            + suffix)
}

def sdk_provided_dependencies = [
        google_api_services_dataflow,
        library.java.avro,
        library.java.google_http_client,
        library.java.google_http_client_gson,
        library.java.jackson_annotations,
        library.java.jackson_core,
        library.java.jackson_databind,
        library.java.joda_time,
        library.java.slf4j_api,
        library.java.vendored_grpc_1_69_0,
]

def sdk_provided_shaded_project_dependencies = [
        ":model:pipeline",
        ":sdks:java:core",
]
def sdk_provided_project_dependencies = [
        ":runners:google-cloud-dataflow-java",
        ":sdks:java:extensions:avro",
        ":sdks:java:extensions:google-cloud-platform-core",
        ":sdks:java:io:google-cloud-platform",
]

// Exclude unneeded dependencies when building jar
def excluded_dependencies = [
        "com.google.auto.service:auto-service",      // Provided scope added from applyJavaNature
        "com.google.auto.value:auto-value",          // Provided scope added from applyJavaNature
        "org.codehaus.jackson:jackson-core-asl",     // Exclude an old version of jackson-core-asl introduced by google-http-client-jackson
        "org.objenesis:objenesis",                   // Transitive dependency introduced from Beam
        library.java.commons_compress,               // Transitive dependency introduced from Beam
        library.java.error_prone_annotations,        // Provided scope added in worker
        library.java.hamcrest,                       // Test only
        library.java.junit,                          // Test only
        library.java.jsonassert,                     // Test only
        library.java.truth                           // Test only
]

applyJavaNature(
        automaticModuleName: 'org.apache.beam.runners.dataflow.worker',
        archivesBaseName: 'beam-runners-google-cloud-dataflow-java-legacy-worker',
        classesTriggerCheckerBugs: [
                'BatchGroupAlsoByWindowAndCombineFn'        : 'TODO: file a bug report',
                'AssignWindowsParDoFnFactory'               : 'TODO: file a bug report',
                'FetchAndFilterStreamingSideInputsOperation': 'https://github.com/typetools/checker-framework/issues/5436',
        ],
        exportJavadoc: false,
        enableSpotbugs: false /* TODO(BEAM-5658): enable spotbugs */,
        shadowJarValidationExcludes: [
                "org/apache/beam/runners/dataflow/worker/**",
                "org/apache/beam/repackaged/beam_runners_google_cloud_dataflow_java_legacy_worker/**",
                // TODO(https://github.com/apache/beam/issues/19114): Move DataflowRunnerHarness class under org.apache.beam.runners.dataflow.worker namespace
                "com/google/cloud/dataflow/worker/DataflowRunnerHarness.class",
                // Allow slf4j implementation worker for logging during pipeline execution
                "org/slf4j/jul/**"
        ],
        generatedClassPatterns: [
                /^org\.apache\.beam\.runners\.dataflow\.worker\.windmill\..*AutoBuilder.*/,
                /^org\.apache\.beam\.runners\.dataflow\.worker\..*AutoBuilder.*/,
        ],
        shadowClosure: {
            // Each included dependency must also include all of its necessary transitive dependencies
            // or have them provided by the users pipeline during job submission. Typically a users
            // pipeline includes :runners:google-cloud-dataflow-java and its transitive dependencies
            // so those dependencies don't need to be shaded (bundled and relocated) away. All other
            // dependencies needed to run the worker must be shaded (bundled and relocated) to prevent
            // ClassNotFound and/or MethodNotFound errors during pipeline execution.
            //
            // Each included dependency should have a matching relocation rule below that ensures
            // that the shaded jar is correctly built.

            dependencies {
                include(dependency(library.java.slf4j_jdk14))
            }

            dependencies {
                include(project(path: ":model:fn-execution", configuration: "shadow"))
            }
            relocate("org.apache.beam.model.fnexecution.v1", getWorkerRelocatedPath("org.apache.beam.model.fnexecution.v1"))

            dependencies {
                include(project(":runners:core-java"))
            }
            relocate("org.apache.beam.runners.core", getWorkerRelocatedPath("org.apache.beam.runners.core"))
            relocate("org.apache.beam.repackaged.beam_runners_core_construction_java", getWorkerRelocatedPath("org.apache.beam.repackaged.beam_runners_core_construction_java"))
            relocate("org.apache.beam.repackaged.beam_runners_core_java", getWorkerRelocatedPath("org.apache.beam.repackaged.beam_runners_core_java"))

            dependencies {
                include(project(":runners:java-fn-execution"))
            }
            relocate("org.apache.beam.runners.fnexecution", getWorkerRelocatedPath("org.apache.beam.runners.fnexecution"))
            relocate("org.apache.beam.repackaged.beam_runners_java_fn_execution", getWorkerRelocatedPath("org.apache.beam.repackaged.beam_runners_java_fn_execution"))

            relocate("org.apache.beam.repackaged.beam_sdks_java_fn_execution", getWorkerRelocatedPath("org.apache.beam.repackaged.beam_sdks_java_fn_execution"))

            dependencies {
                // We have to include jetty-server/jetty-servlet and all of its transitive dependencies
                // which includes several org.eclipse.jetty artifacts + servlet-api
                include(dependency("org.eclipse.jetty:.*:9.4.57.v20241219"))
                include(dependency("javax.servlet:javax.servlet-api:3.1.0"))
            }
            relocate("org.eclipse.jetty", getWorkerRelocatedPath("org.eclipse.jetty"))
            relocate("javax.servlet", getWorkerRelocatedPath("javax.servlet"))

            // We don't relocate windmill since it is already underneath the org.apache.beam.runners.dataflow.worker namespace and never
            // expect a user pipeline to include it. There is also a JNI component that windmill server relies on which makes
            // arbitrary relocation more difficult.
            dependencies {
                include(project(path: ":runners:google-cloud-dataflow-java:worker:windmill", configuration: "shadow"))
            }

            // Include original source files extracted under
            // '$buildDir/original_sources_to_package' to jar
            from "$buildDir/original_sources_to_package"

            exclude "META-INF/LICENSE.txt"
            exclude "about.html"
        })

/******************************************************************************/
// Configure the worker root project

configurations {
    sourceFile

    // Ban these dependencies from all configurations
    all {
        // Ban the usage of AppleJavaExtensions in spotbugs.
        exclude group: "com.apple", module: "AppleJavaExtensions"
    }
}

dependencies {
    implementation enforcedPlatform(library.java.google_cloud_platform_libraries_bom)

    // Note that any dependency that is modified here should also be modified within
    // runners/google-cloud-dataflow-java/worker/build.gradle using the rules provided
    // there.
    sdk_provided_dependencies.each {
        provided(it)
        testImplementation(it)
    }
    sdk_provided_shaded_project_dependencies.each {
        provided project(path: it, configuration: "shadow")
    }
    sdk_provided_project_dependencies.each {
        provided project(path: it)
        testImplementation project(path: it)
    }

    implementation project(path: ":model:fn-execution", configuration: "shadow")
    implementation project(path: ":model:pipeline", configuration: "shadow")
    implementation project(path: ":sdks:java:core", configuration: "shadow")
    implementation project(":runners:core-java")
    implementation project(":runners:java-fn-execution")
    implementation project(path: ":runners:google-cloud-dataflow-java:worker:windmill", configuration: "shadow")
    shadow library.java.vendored_guava_32_1_2_jre

    implementation library.java.google_auth_library_credentials
    implementation library.java.proto_google_common_protos

    // Conscrypt shouldn't be included here because Conscrypt won't work when being shaded.
    // (Context: https://github.com/apache/beam/pull/13846)
    // Conscrypt will be added to runtime dependencies by GrpcVendoring so compileOnly works for now.
    compileOnly "org.conscrypt:conscrypt-openjdk-uber:2.5.1"

    implementation "javax.servlet:javax.servlet-api:3.1.0"
    implementation "org.eclipse.jetty:jetty-server:9.4.57.v20241219"
    implementation "org.eclipse.jetty:jetty-servlet:9.4.57.v20241219"
    implementation library.java.avro
    implementation library.java.jackson_annotations
    implementation library.java.jackson_core
    implementation library.java.jackson_databind
    implementation library.java.joda_time
    implementation library.java.slf4j_api
    implementation library.java.vendored_grpc_1_69_0
    implementation library.java.error_prone_annotations
    permitUnusedDeclared library.java.error_prone_annotations
    runtimeOnly library.java.slf4j_jdk14

    // Any test dependency which intersects with our relocation rules above needs to be relocated
    // as well and placed within the testImplementation configuration. Otherwise we can place it within
    // the shadowTest configuration.
    testImplementation project(path: ":runners:core-java", configuration: "testRuntimeMigration")
    // TODO: excluding Guava until Truth updates it to >32.1.x
    testImplementation(library.java.truth) {
        exclude group: 'com.google.guava', module: 'guava'
    }
    shadowTest project(path: ":sdks:java:extensions:google-cloud-platform-core", configuration: "testRuntimeMigration")
    shadowTest project(path: ":runners:direct-java", configuration: "shadow")
    shadowTest project(path: ":sdks:java:harness", configuration: "shadowTest")
    shadowTest project(path: ":sdks:java:core", configuration: "shadowTest")
    shadowTest library.java.jsonassert
    shadowTest library.java.junit
    shadowTest library.java.mockito_core
}

project.task('validateShadedJarContainsSlf4jJdk14', dependsOn: 'shadowJar') {
    ext.outFile = project.file("${project.reportsDir}/${name}.out")
    inputs.files(project.configurations.shadow.artifacts.files)
            .withPropertyName("shadowArtifactsFiles")
            .withPathSensitivity(PathSensitivity.RELATIVE)
    outputs.files outFile
    doLast {
        project.configurations.shadow.artifacts.files.each {
            FileTree slf4jImpl = project.zipTree(it).matching {
                include "org/slf4j/jul/JDK14LoggerAdapter.class"
            }
            outFile.text = slf4jImpl.files
            if (slf4jImpl.files.isEmpty()) {
                throw new GradleException("Did not find slf4j-jdk14 in Dataflow Worker uber jar")
            }
        }
    }
}

tasks.check.dependsOn project.tasks.validateShadedJarContainsSlf4jJdk14

//TODO(https://github.com/apache/beam/issues/19115): checktyle task should be enabled in the future.
checkstyleMain.enabled = false
checkstyleTest.enabled = false
//TODO(https://github.com/apache/beam/issues/19119): javadoc task should be enabled in the future.
javadoc.enabled = false
