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

// LUCENE-9650: Errorprone on master/gradle no longer works with JDK-16
if (rootProject.runtimeJavaVersion > JavaVersion.VERSION_15) {
  logger.warn("WARNING: errorprone disabled (won't work with JDK ${rootProject.runtimeJavaVersion})")
  return
}

allprojects { prj ->
  plugins.withType(JavaPlugin) {
    prj.apply plugin: 'net.ltgt.errorprone'

    dependencies {
      errorprone("com.google.errorprone:error_prone_core")
    }

    tasks.withType(JavaCompile) { task ->
      options.errorprone.disableWarningsInGeneratedCode = true
      options.errorprone.errorproneArgs = [
          // test
          '-Xep:ExtendingJUnitAssert:OFF',
          '-Xep:UseCorrectAssertInTests:OFF',
          '-Xep:DefaultPackage:OFF',
          '-Xep:FloatingPointLiteralPrecision:OFF',
          '-Xep:CatchFail:OFF',
          '-Xep:TryFailThrowable:OFF',
          '-Xep:MathAbsoluteRandom:OFF',
          '-Xep:AssertionFailureIgnored:OFF',
          '-Xep:JUnit4TestNotRun:OFF',
          '-Xep:FallThrough:OFF',
          '-Xep:CatchAndPrintStackTrace:OFF',
          '-Xep:ToStringReturnsNull:OFF',
          '-Xep:ArrayAsKeyOfSetOrMap:OFF',
          '-Xep:StaticAssignmentInConstructor:OFF',
          '-Xep:SelfAssignment:OFF',
          '-Xep:InvalidPatternSyntax:OFF',
          '-Xep:MissingFail:OFF',
          '-Xep:LossyPrimitiveCompare:OFF',
          '-Xep:ComparableType:OFF',
          '-Xep:InfiniteRecursion:OFF',
          '-Xep:MisusedDayOfYear:OFF',
          '-Xep:FloatingPointAssertionWithinEpsilon:OFF',

          '-Xep:ThrowNull:OFF',
          '-Xep:StaticGuardedByInstance:OFF',
          '-Xep:ArrayHashCode:OFF',
          '-Xep:ArrayEquals:OFF',
          '-Xep:IdentityBinaryExpression:OFF',
          '-Xep:ComplexBooleanConstant:OFF',
          '-Xep:ComplexBooleanConstant:OFF',
          '-Xep:StreamResourceLeak:OFF',
          '-Xep:UnnecessaryLambda:OFF',
          '-Xep:ObjectToString:OFF',
          '-Xep:URLEqualsHashCode:OFF',
          '-Xep:DoubleBraceInitialization:OFF',
          '-Xep:ShortCircuitBoolean:OFF',
          '-Xep:InputStreamSlowMultibyteRead:OFF',
          '-Xep:NonCanonicalType:OFF',
          '-Xep:CollectionIncompatibleType:OFF',
          '-Xep:TypeParameterShadowing:OFF',
          '-Xep:ThreadJoinLoop:OFF',
          '-Xep:MutableConstantField:OFF',
          '-Xep:ReturnValueIgnored:OFF',
          '-Xep:CollectionIncompatibleType:OFF',
          '-Xep:SameNameButDifferent:OFF',
          '-Xep:InvalidParam:OFF',
          '-Xep:CompareToZero:OFF',
          '-Xep:DoubleCheckedLocking:OFF',
          '-Xep:BadShiftAmount:OFF',
          '-Xep:CollectionUndefinedEquality:OFF',
          '-Xep:UnescapedEntity:OFF',
          '-Xep:BoxedPrimitiveEquality:OFF',
          '-Xep:LogicalAssignment:OFF',
          '-Xep:DoubleCheckedLocking:OFF',
          '-Xep:AmbiguousMethodReference:OFF',
          '-Xep:FormatString:OFF',
          '-Xep:InstanceOfAndCastMatchWrongType:OFF',
          '-Xep:ModifyCollectionInEnhancedForLoop:OFF',
          '-Xep:JavaLangClash:OFF',
          '-Xep:TypeParameterUnusedInFormals:OFF',
          '-Xep:UnusedNestedClass:OFF',
          '-Xep:OverrideThrowableToString:OFF',
          '-Xep:FutureReturnValueIgnored:OFF',
          '-Xep:BadInstanceof:OFF',
          '-Xep:UnusedNestedClass:OFF',
          '-Xep:OverrideThrowableToString:OFF',
          '-Xep:EqualsIncompatibleType:OFF',
          '-Xep:ByteBufferBackingArray:OFF',
          '-Xep:ByteBufferBackingArray:OFF',
          '-Xep:UnusedMethod:OFF',
          '-Xep:ObjectsHashCodePrimitive:OFF',
          '-Xep:ObjectsHashCodePrimitive:OFF',
          '-Xep:UnnecessaryAnonymousClass:OFF',
          '-Xep:BoxedPrimitiveConstructor:OFF',
          '-Xep:ArgumentSelectionDefectChecker:OFF',
          '-Xep:StringSplitter:OFF',
          '-Xep:MixedMutabilityReturnType:OFF',
          '-Xep:EqualsUnsafeCast:OFF',
          '-Xep:OperatorPrecedence:OFF',
          '-Xep:HidingField:OFF',
          '-Xep:ThreadPriorityCheck:OFF',
          '-Xep:InlineFormatString:OFF',
          '-Xep:EqualsUnsafeCast:OFF',
          '-Xep:UnsynchronizedOverridesSynchronized:OFF',
          '-Xep:OperatorPrecedence:OFF',
          '-Xep:ArrayToString:OFF',
          '-Xep:ClassCanBeStatic:OFF',
          '-Xep:InvalidInlineTag:OFF',
          '-Xep:EmptyCatch:OFF',
          '-Xep:UnnecessaryParentheses:OFF',
          '-Xep:AlmostJavadoc:OFF',
          '-Xep:Finally:OFF',
          '-Xep:ImmutableEnumChecker:OFF',
          '-Xep:NonAtomicVolatileUpdate:OFF',
          '-Xep:MutablePublicArray:OFF',
          '-Xep:LockNotBeforeTry:OFF',
          '-Xep:WaitNotInLoop:OFF',
          '-Xep:UndefinedEquals:OFF',
          '-Xep:JdkObsolete:OFF',
          '-Xep:NarrowingCompoundAssignment:OFF',
          '-Xep:InconsistentCapitalization:OFF',
          '-Xep:IntLongMath:OFF',
          '-Xep:SynchronizeOnNonFinalField:OFF',
          '-Xep:ThreadLocalUsage:OFF',
          '-Xep:ProtectedMembersInFinalClass:OFF',
          '-Xep:BadImport:OFF',
          '-Xep:InconsistentHashCode:OFF',
          '-Xep:MissingOverride:OFF',
          '-Xep:EqualsGetClass:OFF',
          '-Xep:PublicConstructorForAbstractClass:OFF',
          '-Xep:EscapedEntity:OFF',
          '-Xep:ModifiedButNotUsed:OFF',
          '-Xep:ReferenceEquality:OFF',
          '-Xep:InvalidBlockTag:OFF',
          '-Xep:MissingSummary:OFF',
          '-Xep:UnusedVariable:OFF'
      ]
    }
  }
}
