/*
 * 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.
 */
// This is a base file to set up cross language tests for different runners
import static org.apache.beam.gradle.BeamModulePlugin.CrossLanguageTask
project.evaluationDependsOn(":sdks:python")

// ******** Java GCP expansion service ********
// Note: this only runs cross-language tests that use the Java GCP expansion service
// To run tests that use another expansion service, create a new CrossLanguageTask with the
// relevant fields as done here, then add it to `xlangTasks`.
def gcpExpansionPath = project.project(':sdks:java:io:google-cloud-platform:expansion-service').getPath()
def ioExpansionPath = project.project(':sdks:java:io:expansion-service').getPath()
def messagingExpansionPath = project.project(':sdks:java:io:messaging-expansion-service').getPath()
// Properties that are common across runners.
// Used to launch the expansion service, collect the right tests, and cleanup afterwards
def gcpXlang = new CrossLanguageTask().tap {
    name = "gcpCrossLanguage"
    expansionProjectPaths = [gcpExpansionPath]
    collectMarker = "uses_gcp_java_expansion_service"
}

def ioXlang = new CrossLanguageTask().tap {
    name = "ioCrossLanguage"
    expansionProjectPaths = [ioExpansionPath]
    collectMarker = "uses_io_java_expansion_service"
    //See .test-infra/kafka/bitnami/README.md for setup instructions
    additionalEnvs = ["KAFKA_BOOTSTRAP_SERVER":project.findProperty('kafkaBootstrapServer')]
}

def messagingXlang = new CrossLanguageTask().tap {
    name = "messagingCrossLanguage"
    expansionProjectPaths = [messagingExpansionPath]
    collectMarker = "uses_messaging_java_expansion_service"
}

// This list should include all expansion service targets in sdks/python/standard_expansion_services.yaml
def servicesToGenerateFrom = [ioExpansionPath, messagingExpansionPath, gcpExpansionPath]
def xlangWrapperValidation = new CrossLanguageTask().tap {
    name = "xlangWrapperValidation"
    expansionProjectPaths = servicesToGenerateFrom
    collectMarker = "xlang_wrapper_generation"
    // update Jinja2 bounds in pyproject.toml as well
    additionalDeps = ['\"Jinja2>=2.7.1,<4.0.0\"']
}

// List of task metadata objects to create cross-language tasks from.
// Each object contains the minimum relevant metadata.
def xlangTasks = [gcpXlang, ioXlang, messagingXlang, xlangWrapperValidation]

ext.xlangTasks = xlangTasks