/*
 * 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 CommonJobProperties as commonJobProperties

// These jobs list details about each beam runner, to clarify what software
// is on each machine.
def nums = 1..16
nums.each {
  def machine = "apache-beam-jenkins-${it}"
  job("beam_Inventory_${machine}") {
    description("Run inventory on ${machine}")

    // Set common parameters.
    commonJobProperties.setTopLevelMainJobProperties(delegate)

    // Sets that this is a cron job.
    commonJobProperties.setCronJob(delegate, '45 18 * * *')

    // Allows triggering this build against pull requests.
    commonJobProperties.enablePhraseTriggeringFromPullRequest(
      delegate,
      "Machine Inventory ${machine}",
      "Run Inventory ${machine}")

    parameters {
      nodeParam('TEST_HOST') {
        description("Select test host ${machine}")
        defaultNodes([machine])
        allowedNodes([machine])
        trigger('multiSelectionDisallowed')
        eligibility('IgnoreOfflineNodeEligibility')
      }
    }

    steps {
      shell('ls /home/jenkins/tools')
      shell('ls /home/jenkins/tools/*')
      shell('python --version || echo "python not found"')
      shell('python3 --version || echo "python3 not found"')
      shell('python3.5 --version || echo "python3.5 not found"')
      shell('python3.6 --version || echo "python3.6 not found"')
      shell('python3.7 --version || echo "python3.7 not found"')
      shell('/home/jenkins/tools/maven/latest/mvn -v || echo "mvn not found"')
      shell('/home/jenkins/tools/gradle4.3/gradle -v || echo "gradle not found"')
      shell('gcloud -v || echo "gcloud not found"')
      shell('kubectl version || echo "kubectl not found"')
      shell('virtualenv -p python2.7 test27 && . ./test27/bin/activate && python --version && deactivate || echo "python 2.7 not found"')
      shell('virtualenv -p python3.5 test35 && . ./test35/bin/activate && python --version && deactivate || echo "python 3.5 not found"')
      shell('virtualenv -p python3.6 test36 && . ./test36/bin/activate && python --version && deactivate || echo "python 3.6 not found"')
      shell('virtualenv -p python3.7 test37 && . ./test37/bin/activate && python --version && deactivate || echo "python 3.7 not found"')
      shell('echo "Maven home $MAVEN_HOME"')
      shell('env')
      shell('docker system prune --all --filter until=24h --force')
    }
  }
}
