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

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath group: 'org.yaml', name: 'snakeyaml', version: '2.2'
  }
}

/** check that yml are valid */
task check {
  doLast {
    List<String> errors = []
    fileTree("${project.projectDir}/workflows").matching {
      include "*.yml"
      include "*.yaml"
    }.each {
      def fname = it.getName()
      // attempt load yml to make sure its valid
      def workflow = new org.yaml.snakeyaml.Yaml().load(it.newInputStream())

      // additional guards to ensure tests configured in same way
      if ( fname.startsWith("beam_PreCommit") || fname.startsWith("beam_PostCommit") ) {
        List paths
        try {
          paths = workflow.getAt(true).pull_request_target.paths as List
        } catch (Exception e) {
          errors.add("Fail to get the trigger path for ${fname}. " +
                    "Make sure it has a pull_request_target trigger.")
          return
        }

        // precommit and postcommit should be triggered by this specific file
        // this is to ensure not missing test during release branch verification
        if (paths != null && !paths.contains('release/trigger_all_tests.json') && !fname.toLowerCase().contains('sickbay') && !workflow.name.toLowerCase().contains('disabled')) {
          errors.add("Error validating ${fname}: " +
                  "Please add 'release/trigger_all_tests.json' to the trigger path")
          return
        }

        // postcommit should be triggered by a specific file so that there is a way to exercise post for open PR
        // TODO(https://github.com/apache/beam/issues/28909)
        //  remove file match trigger once a better trigger (e.g. comment trigger) is implemented
        if (fname.startsWith("beam_PostCommit")) {
          String triggerFile = '.github/trigger_files/' + fname.take(fname.lastIndexOf('.')) + '.json'
          if (paths != null && !paths.contains(triggerFile)) {
            errors.add("Error validating ${fname}: " +
                    "Please add ${triggerFile} to the trigger path")
            return
          }
        }
      }
    }
    if (!errors.isEmpty()) {
      throw new GradleException("Check failed: " + errors.join('\n'))
    }
  }
}

task preCommit {
  dependsOn check
}