// 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 file contains common tasks and configuration for checking the quality of the code.

apply plugin: "checkstyle" // Ensures Java code follows the defined coding style.
apply plugin: "com.github.spotbugs"   // Performs static code analysis to look for bugs in Java code.
apply plugin: "com.github.ben-manes.versions" // Provides a task to determine which dependencies have updates.
apply plugin: "ru.vyarus.animalsniffer" // Ensures Java code uses APIs from a particular version of Java.
apply plugin: "scalafmt" // Automatically formats Scala code on each build.

def ignoreCheckFailures = false
if (propertyExists("ignoreCheckFailures")) {
  ignoreCheckFailures = true
}

checkstyle {
  toolVersion = versions.checkstyle
  configDir = file("$rootProject.projectDir/config/checkstyle")
  ignoreFailures = ignoreCheckFailures
  maxWarnings = 0
  showViolations = true
}

// Create an aggregate checkstyle task.
// This simplifies running checkstyle on all the code by only needing one task instead of multiple in your command.
task checkstyle(dependsOn: [checkstyleMain, checkstyleTest], group: "Verification") {
  description = "Run Checkstyle analysis."
}

spotbugs {
  toolVersion = versions.spotBugs
  ignoreFailures = ignoreCheckFailures
  effort = "max"
  reportLevel = "low"
  excludeFilter = file("$rootProject.projectDir/config/spotbugs/excludeFilter.xml")
}

tasks.withType(com.github.spotbugs.snom.SpotBugsTask) {
  reports {
    xml.enabled false
    html.enabled true
  }
}

// Create an aggregate spotbugs task.
// This simplifies running spotbugs on all the code by only needing one task instead of multiple in your command.
task spotbugs(dependsOn: [spotbugsMain, spotbugsTest], group: "Verification") {
  description = "Run SpotBugs analysis."
}

scalafmt {
  configFilePath = "$rootDir/.scalafmt.conf"
}

// Run scalafmt on compile.
tasks.withType(ScalaCompile) {
  if (!propertyExists("skipFormat")) {
     dependsOn("scalafmtAll")
  }
}

// Errorprone doesn't support Java 12+
// https://github.com/google/error-prone/issues/1106
if(!JavaVersion.current().isJava12Compatible()) {
  apply plugin: "net.ltgt.errorprone" // Performs static code analysis to look for bugs in Java code.

  // Configure error-prone.
  // Running with '-Derrorprone-fix=...' can instruct error-prone to automatically fix issues.
  tasks.withType(JavaCompile) {
    options.errorprone {
      disableWarningsInGeneratedCode = true
      excludedPaths = '.*/build/generated.*/.*'
      allErrorsAsWarnings = false
      def fix = propertyWithDefault("errorprone-fix", "")
      if (!fix.isEmpty()) {
        errorproneArgs += ['-XepPatchChecks:' + fix, '-XepPatchLocation:IN_PLACE']
      }
    }
  }
  dependencies {
    // Set a specific version of Error Prone
    errorprone libs.errorProne
    // Configure Error Prone to use it's own static javac as described here:
    // https://github.com/tbroyer/gradle-errorprone-plugin#jdk-8-support
    errorproneJavac libs.errorProneJavac
  }
}

// Define a Java API signature for use by animal-sniffer. It'll enforce that all
// Java API usage adheres to this signature.
dependencies {
  signature "org.codehaus.mojo.signature:java1$javaCompatibility:1.0@signature"
}

// Create an aggregate animal-sniffer task.
// This simplifies running animal-sniffer on all the code by only needing one task instead of multiple in your command.
task animalsniffer(dependsOn: [animalsnifferMain, animalsnifferTest], group: "Verification") {
  description = "Run animal-sniffer analysis."
}

// Configure the versions plugin to only show dependency updates for released versions.
dependencyUpdates {
  gradleReleaseChannel = "current"
  revision = "release"
  resolutionStrategy {
    componentSelection { rules ->
      rules.all { ComponentSelection selection ->
        boolean rejected = ["snap", "alpha", "beta", "rc", "cr", "m"].any { qualifier ->
          selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-].*/
        }
        if (rejected) {
          selection.reject("Release candidate")
        }
      }
    }
  }
}
