/*
 * 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.
 */

import groovy.json.JsonOutput
plugins { id 'org.apache.beam.module' }

// Shade away runner execution utilities till because this causes ServiceLoader conflicts with
// TransformPayloadTranslatorRegistrar amongst other runners. This only happens in the DirectRunner
// because it is likely to appear on the classpath of another runner.
def dependOnProjects = [":runners:core-construction-java",
                        ":runners:core-java",
                        ":runners:local-java",
                        ":runners:java-fn-execution",
                        ":sdks:java:fn-execution"]

applyJavaNature(
        automaticModuleName: 'org.apache.beam.runners.direct',
        enableChecker: false,
        ignoreRawtypeErrors: true,
        shadowClosure: {
          dependencies {
            dependOnProjects.each {
              include(project(path: it, configuration: "shadow"))
            }
          }
          relocate "org.apache.beam.runners.core", getJavaRelocatedPath("runners.core")
          relocate "org.apache.beam.runners.fnexecution", getJavaRelocatedPath("runners.fnexecution")
          relocate "org.apache.beam.sdk.fn", getJavaRelocatedPath("sdk.fn")
          relocate "org.apache.beam.runners.local", getJavaRelocatedPath("runners.local")
        })

description = "Apache Beam :: Runners :: Direct Java"

/*
 * We need to rely on manually specifying these evaluationDependsOn to ensure that
 * the following projects are evaluated before we evaluate this project. This is because
 * we are attempting to reference the "sourceSets.test.output" directly.
 */
evaluationDependsOn(":runners:core-construction-java")
evaluationDependsOn(":runners:core-java")
evaluationDependsOn(":sdks:java:core")

configurations {
  needsRunner
  validatesRunner
}

dependencies {
  shadow library.java.vendored_guava_26_0_jre
  shadow project(path: ":model:pipeline", configuration: "shadow")
  dependOnProjects.each {
    compile project(it)
  }
  shadow project(path: ":sdks:java:core", configuration: "shadow")
  shadow library.java.vendored_grpc_1_26_0
  shadow library.java.joda_time
  shadow library.java.slf4j_api
  shadow library.java.args4j
  provided library.java.hamcrest_core
  provided library.java.junit
  shadowTest project(path: ":sdks:java:core", configuration: "shadowTest")
  shadowTest project(path: ":runners:core-java", configuration: "testRuntime")
  shadowTest library.java.slf4j_jdk14
  shadowTest library.java.mockito_core
  shadowTest library.java.stax2_api
  shadowTest library.java.woodstox_core_asl
  shadowTest library.java.google_cloud_dataflow_java_proto_library_all
  shadowTest library.java.jackson_dataformat_yaml
  needsRunner project(path: ":runners:core-construction-java", configuration: "testRuntime")
  needsRunner project(path: ":runners:core-java", configuration: "testRuntime")
  needsRunner project(path: ":sdks:java:core", configuration: "shadowTest")
  needsRunner project(path: project.path, configuration: "shadow")
  needsRunner project(path: project.path, configuration: "shadowTest")
  validatesRunner project(path: ":runners:core-construction-java", configuration: "testRuntime")
  validatesRunner project(path: ":runners:core-java", configuration: "testRuntime")
  validatesRunner project(path: ":sdks:java:core", configuration: "shadowTest")
  validatesRunner project(path: project.path, configuration: "shadow")
  validatesRunner project(path: project.path, configuration: "shadowTest")
}

task needsRunnerTests(type: Test) {
  group = "Verification"
  description = "Runs tests that require a runner to validate that piplines/transforms work correctly"

  testLogging.showStandardStreams = true

  def pipelineOptions = JsonOutput.toJson(["--runner=DirectRunner", "--runnerDeterminedSharding=false"])
  systemProperty "beamTestPipelineOptions", pipelineOptions

  classpath = configurations.needsRunner
  // NOTE: We only add to the test class dirs to ensure that the direct runner
  // tests (i.e., those from this subproject) get scanned.
  testClassesDirs += files(project(":runners:core-construction-java").sourceSets.test.output.classesDirs)
  testClassesDirs += files(project(":runners:core-java").sourceSets.test.output.classesDirs)
  testClassesDirs += files(project(":sdks:java:core").sourceSets.test.output.classesDirs)
  useJUnit {
    includeCategories "org.apache.beam.sdk.testing.NeedsRunner"
    excludeCategories "org.apache.beam.sdk.testing.LargeKeys\$Above100MB"
    // MetricsPusher isn't implemented in direct runner
    excludeCategories "org.apache.beam.sdk.testing.UsesMetricsPusher"
    excludeCategories "org.apache.beam.sdk.testing.UsesCrossLanguageTransforms"
    excludeCategories 'org.apache.beam.sdk.testing.UsesBundleFinalizer'
  }
  testLogging {
    outputs.upToDateWhen {false}
    showStandardStreams = true
  }
}

// NOTE: This will also run 'NeedsRunner' tests, which are run in the :needsRunnerTests task as well.
// The intention of this task is to mirror the :validatesRunner configuration for other runners,
// such that the test suite can be validated on the in-process DirectRunner.
task validatesRunner(type: Test) {
  group = "Verification"
  description "Validates Direct runner"

  def pipelineOptions = JsonOutput.toJson(["--runner=DirectRunner", "--runnerDeterminedSharding=false"])
  systemProperty "beamTestPipelineOptions", pipelineOptions

  classpath = configurations.validatesRunner
  // NOTE: We only add to the test class dirs to ensure that the direct runner
  // tests (i.e., those from this subproject) get scanned.
  testClassesDirs += files(project(":runners:core-construction-java").sourceSets.test.output.classesDirs)
  testClassesDirs += files(project(":runners:core-java").sourceSets.test.output.classesDirs)
  testClassesDirs += files(project(":sdks:java:core").sourceSets.test.output.classesDirs)
  useJUnit {
    includeCategories "org.apache.beam.sdk.testing.ValidatesRunner"
    excludeCategories "org.apache.beam.sdk.testing.LargeKeys\$Above100MB"
    excludeCategories 'org.apache.beam.sdk.testing.UsesMetricsPusher'
    excludeCategories "org.apache.beam.sdk.testing.UsesCrossLanguageTransforms"
  }
}

def gcpProject = project.findProperty('gcpProject') ?: 'apache-beam-testing'
def gcsBucket = project.findProperty('gcsBucket') ?: 'temp-storage-for-release-validation-tests/nightly-snapshot-validation'
def bqDataset = project.findProperty('bqDataset') ?: 'beam_postrelease_mobile_gaming'
def pubsubTopic = project.findProperty('pubsubTopic') ?: 'java_mobile_gaming_topic'

// Generates :runners:direct-java:runQuickstartJavaDirect
createJavaExamplesArchetypeValidationTask(type: 'Quickstart', runner: 'Direct')

// Generates :runners:direct-java:runMobileGamingJavaDirect
createJavaExamplesArchetypeValidationTask(type: 'MobileGaming',
  runner: 'Direct',
  gcpProject: gcpProject,
  gcsBucket: gcsBucket,
  bqDataset: bqDataset,
  pubsubTopic: pubsubTopic)
