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

/**
 * Main Flink Runner build file shared by all of its build targets.
 * The file needs to be parameterized by the Flink version and the source directories.
 *
 * See build.gradle files for an example of how to use this script.
 */

import groovy.json.JsonOutput

apply plugin: 'org.apache.beam.module'
applyJavaNature(
    automaticModuleName: 'org.apache.beam.runners.flink',
    enableChecker: false,
    ignoreRawtypeErrors: true,
    archivesBaseName: (project.hasProperty('archives_base_name') ? archives_base_name : archivesBaseName))

description = "Apache Beam :: Runners :: Flink $flink_version"

/*
 * 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(":sdks:java:core")
evaluationDependsOn(":runners:core-java")

/*
 * Copy & merge source overrides into build directory.
 */
def sourceOverridesBase = "${project.buildDir}/source-overrides/src"

def copySourceOverrides = tasks.register('copySourceOverrides', Copy) {
  it.from main_source_overrides
  it.into "${sourceOverridesBase}/main/java"
  it.duplicatesStrategy DuplicatesStrategy.INCLUDE
}
compileJava.dependsOn copySourceOverrides

def copyResourcesOverrides = tasks.register('copyResourcesOverrides', Copy) {
  it.from main_resources_overrides
  it.into "${sourceOverridesBase}/main/resources"
  it.duplicatesStrategy DuplicatesStrategy.INCLUDE
}
compileJava.dependsOn copyResourcesOverrides

def copyTestSourceOverrides = tasks.register('copyTestSourceOverrides', Copy) {
  it.from test_source_overrides
  it.into "${sourceOverridesBase}/test/java"
  it.duplicatesStrategy DuplicatesStrategy.INCLUDE
}
compileTestJava.dependsOn copyTestSourceOverrides

def copyTestResourcesOverrides = tasks.register('copyTestResourcesOverrides', Copy) {
  it.from test_resources_overrides
  it.into "${sourceOverridesBase}/test/resources"
  it.duplicatesStrategy DuplicatesStrategy.INCLUDE
}
compileJava.dependsOn copyTestResourcesOverrides

/*
 * We have to explicitly set all directories here to make sure each
 * version of Flink has the correct overrides set.
 */
def sourceBase = "${project.projectDir}/../src"
sourceSets {
  main {
    java {
      srcDirs = ["${sourceBase}/main/java", "${sourceOverridesBase}/main/java"]
    }
    resources {
      srcDirs = ["${sourceBase}/main/resources", "${sourceOverridesBase}/main/resources"]
    }
  }
  test {
    java {
      srcDirs = ["${sourceBase}/test/java", "${sourceOverridesBase}/test/java"]
    }
    resources {
      srcDirs = ["${sourceBase}/test/resources", "${sourceOverridesBase}/test/resources"]
    }
  }
}

test {
  systemProperty "log4j.configuration", "log4j-test.properties"
  // Change log level to debug:
  // systemProperty "org.slf4j.simpleLogger.defaultLogLevel", "debug"
  // Change log level to debug only for the package and nested packages:
  // systemProperty "org.slf4j.simpleLogger.log.org.apache.beam.runners.flink.translation.wrappers.streaming", "debug"
  jvmArgs "-XX:-UseGCOverheadLimit"
  if (System.getProperty("beamSurefireArgline")) {
    jvmArgs System.getProperty("beamSurefireArgline")
  }
  // TODO Running tests of all Flink versions in parallel can be too harsh on Jenkins memory
  // Run them serially for now, to avoid "Exit code 137", i.e. Jenkins host killing the Gradle test process
  if (project.path == ":runners:flink:1.9") {
    mustRunAfter(":runners:flink:1.8:test")
  } else if (project.path == ":runners:flink:1.10") {
    mustRunAfter(":runners:flink:1.8:test")
    mustRunAfter(":runners:flink:1.9:test")
  } else if (project.path == ":runners:flink:1.11") {
    mustRunAfter(":runners:flink:1.8:test")
    mustRunAfter(":runners:flink:1.9:test")
    mustRunAfter(":runners:flink:1.10:test")
  }
}

configurations {
  validatesRunner
  miniCluster
}

dependencies {
  compileOnly project(":sdks:java:build-tools")
  compile library.java.vendored_guava_26_0_jre
  compile project(path: ":sdks:java:core", configuration: "shadow")
  compile project(":runners:core-java")
  compile project(":runners:core-construction-java")
  compile project(":runners:java-fn-execution")
  compile project(":runners:java-job-service")
  compile project(":sdks:java:extensions:google-cloud-platform-core")
  compile library.java.vendored_grpc_1_26_0
  compile library.java.jackson_annotations
  compile library.java.slf4j_api
  compile library.java.joda_time
  compile library.java.args4j
  compile "org.apache.flink:flink-clients_2.11:$flink_version"
  compile "org.apache.flink:flink-core:$flink_version"
  compile "org.apache.flink:flink-metrics-core:$flink_version"
  compile "org.apache.flink:flink-java:$flink_version"
  compile "org.apache.flink:flink-runtime_2.11:$flink_version"
  compile "org.apache.flink:flink-streaming-java_2.11:$flink_version"
  testCompile project(path: ":sdks:java:core", configuration: "shadowTest")
  // FlinkStateInternalsTest extends abstract StateInternalsTest
  testCompile project(path: ":runners:core-java", configuration: "testRuntime")
  testCompile library.java.hamcrest_core
  testCompile library.java.junit
  testCompile library.java.mockito_core
  testCompile library.java.powermock
  testCompile library.java.google_api_services_bigquery
  testCompile project(":sdks:java:io:google-cloud-platform")
  testCompile library.java.jackson_dataformat_yaml
  testCompile "org.apache.flink:flink-core:$flink_version:tests"
  testCompile "org.apache.flink:flink-runtime_2.11:$flink_version:tests"
  testCompile "org.apache.flink:flink-streaming-java_2.11:$flink_version:tests"
  testCompile "org.apache.flink:flink-test-utils_2.11:$flink_version"
  testCompile project(":sdks:java:harness")
  testRuntimeOnly library.java.slf4j_simple
  validatesRunner project(path: ":sdks:java:core", configuration: "shadowTest")
  validatesRunner project(path: ":runners:core-java", configuration: "testRuntime")
  validatesRunner project(project.path)
  miniCluster "org.apache.flink:flink-runtime-web_2.11:$flink_version"
}

class ValidatesRunnerConfig {
  String name
  boolean streaming
  boolean checkpointing
}

def createValidatesRunnerTask(Map m) {
  def config = m as ValidatesRunnerConfig
  tasks.register(config.name, Test) {
    group = "Verification"
    def runnerType = config.streaming ? "streaming" : "batch"
    description = "Validates the ${runnerType} runner"
    def pipelineOptionsArray = ["--runner=TestFlinkRunner",
                                "--streaming=${config.streaming}",
                                "--parallelism=2",
    ]
    if (config.checkpointing) {
      pipelineOptionsArray.addAll([
              "--checkpointingInterval=3000",
              "--shutdownSourcesAfterIdleMs=60000",
      ])
    }
    def pipelineOptions = JsonOutput.toJson(pipelineOptionsArray)
    systemProperty "beamTestPipelineOptions", pipelineOptions
    classpath = configurations.validatesRunner
    testClassesDirs = files(
      project(":sdks:java:core").sourceSets.test.output.classesDirs,
      project(":runners:core-java").sourceSets.test.output.classesDirs,
    )
    // maxParallelForks decreased from 4 in order to avoid OOM errors
    maxParallelForks 2
    useJUnit {
      if (config.checkpointing) {
        includeCategories 'org.apache.beam.sdk.testing.UsesBundleFinalizer'
        // TestStreamSource does not support checkpointing
        excludeCategories 'org.apache.beam.sdk.testing.UsesTestStream'
      } else {
        includeCategories 'org.apache.beam.sdk.testing.ValidatesRunner'
        excludeCategories 'org.apache.beam.sdk.testing.UsesBundleFinalizer'
      }
      excludeCategories 'org.apache.beam.sdk.testing.FlattenWithHeterogeneousCoders'
      excludeCategories 'org.apache.beam.sdk.testing.LargeKeys$Above100MB'
      excludeCategories 'org.apache.beam.sdk.testing.UsesCommittedMetrics'
      excludeCategories 'org.apache.beam.sdk.testing.UsesSystemMetrics'
      excludeCategories 'org.apache.beam.sdk.testing.UsesOnWindowExpiration'
      excludeCategories 'org.apache.beam.sdk.testing.UsesStrictTimerOrdering'
      excludeCategories 'org.apache.beam.sdk.testing.UsesOrderedListState'
      if (config.streaming) {
        excludeCategories 'org.apache.beam.sdk.testing.UsesTimerMap'
        excludeCategories 'org.apache.beam.sdk.testing.UsesTestStreamWithMultipleStages'  // BEAM-8598
        excludeCategories 'org.apache.beam.sdk.testing.UsesTestStreamWithProcessingTime'
      } else {
        excludeCategories 'org.apache.beam.sdk.testing.UsesBundleFinalizer'
        excludeCategories 'org.apache.beam.sdk.testing.UsesUnboundedPCollections'
        excludeCategories 'org.apache.beam.sdk.testing.UsesUnboundedSplittableParDo'
        excludeCategories 'org.apache.beam.sdk.testing.UsesTestStream'
      }
    }
  }
}

createValidatesRunnerTask(name: "validatesRunnerBatch", streaming: false)
createValidatesRunnerTask(name: "validatesRunnerStreaming", streaming: true)
// We specifically have a variant which runs with checkpointing enabled for the
// tests that require it since running a checkpoint variant is significantly
// slower since we have to wait shutdownSourcesAfterIdleMs before the source
// can shutdown because of https://issues.apache.org/jira/browse/FLINK-2491
// not supporting checkpointing when an operator has been shutdown.
createValidatesRunnerTask(name: "validatesRunnerStreamingCheckpointing", streaming: true, checkpointing: true)

tasks.register('validatesRunner') {
  group = 'Verification'
  description "Validates Flink runner"
  dependsOn validatesRunnerBatch
  dependsOn validatesRunnerStreaming
  dependsOn validatesRunnerStreamingCheckpointing
}

// Generates :runners:flink:1.10:runQuickstartJavaFlinkLocal
createJavaExamplesArchetypeValidationTask(type: 'Quickstart', runner: 'FlinkLocal')

/**
 * Updates the documentation with the current pipeline options.
 */
def createPipelineOptionsTableTask(String target) {
  tasks.register("generatePipelineOptionsTable${target}", JavaExec) {
    group = 'Website'
    description = "Generates a table with pipeline options for the Flink Runner documentation page"
    classpath = sourceSets.test.runtimeClasspath
    main = 'org.apache.beam.runners.flink.website.PipelineOptionsTableGenerator'
    args = [target]
    standardOutput = new ByteArrayOutputStream()
    doLast {
      def dest = file("${project(':website').getProjectDir()}/www/site/layouts/shortcodes/flink_${target.toLowerCase()}_pipeline_options.html")
      if (!dest.exists()) {
        throw new GradleException("Pipeline options file is not in expected location: ${dest}")
      }
      dest.write(standardOutput.toString())
    }
  }
}
createPipelineOptionsTableTask('Java')
createPipelineOptionsTableTask('Python')
// Update the pipeline options documentation before running the tests
test.dependsOn(generatePipelineOptionsTableJava)
test.dependsOn(generatePipelineOptionsTablePython)
