<?xml version="1.0"?>
<!--
  ~ 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.
  -->

<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">

<module name="Checker">

  <property name="cacheFile" value="${cache_file}"/>

  <property name="localeLanguage" value="en"/>
  <property name="charset" value="UTF-8"/>
  <property name="severity" value="error"/>
  <property name="fileExtensions"
            value="java, groovy, xml, xsd, dtd, htm, html, txt, properties"/>

  <!-- Verify that EVERY source file has the appropriate license -->
  <module name="RegexpHeader">
    <property name="headerFile" value="${config_loc}/java.header.regex"/>
    <property name="multiLines" value="10"/>
    <property name="fileExtensions" value="java, groovy"/>
  </module>

  <!-- Miscellaneous -->
  <module name="FileTabCharacter">
    <!-- No tabs allowed! -->
    <property name="fileExtensions" value="java, kt, kts, groovy, xml, xsd, dtd, htm, html, txt, properties"/>
  </module>
  <module name="NewlineAtEndOfFile"/>
  <module name="RegexpSingleline">
    <property name="message" value="Trailing whitespace"/>
    <property name="format" value="\s$"/>
  </module>
  <module name="RegexpMultiline">
    <!-- No more than 2 blank lines allowed. -->
    <property name="format" value="\r?\n[\t ]*\r?\n[\t ]*\r?\n[\t ]*\r?\n"/>
    <property name="fileExtensions" value="java, kt, kts, groovy, xml, properties"/>
    <property name="message" value="Unnecessary consecutive lines"/>
  </module>
  <module name="RegexpOnFilename">
    <property name="folderPattern" value="[\\/]src[\\/]\w+[\\/]java[\\/]"/>
    <property name="fileNamePattern" value="\.java$"/>
    <property name="match" value="false"/>
    <message key="regexp.filepath.mismatch" value="Only java files should be located in the ''src/*/java'' folders."/>
  </module>
  <module name="UniqueProperties">
    <property name="fileExtensions" value="properties"/>
  </module>

  <!-- Size Violations -->
  <module name="FileLength">
    <property name="fileExtensions" value="java, kt, kts, groovy"/>
  </module>

  <module name="LineLength">
    <!-- TODO: reduce this to 120 -->
    <property name="max" value="160"/>
    <property name="fileExtensions" value="java, kt, kts, groovy"/>
  </module>

  <module name="TreeWalker">

    <!-- Annotations -->
    <!--<module name="MissingDeprecated"/>-->
    <module name="MissingOverride"/>

    <!-- Block checks -->
    <module name="AvoidNestedBlocks"/>
    <module name="EmptyBlock"/>
    <module name="EmptyCatchBlock">
      <property name="exceptionVariableName" value="expected|ignore"/>
    </module>
    <!--<module name="LeftCurly"/>-->
    <!--<module name="RightCurly"/>-->
    <module name="NeedBraces"/>

    <!--Class Design-->
    <!--<module name="FinalClass"/>-->
    <!--<module name="HideUtilityClassConstructor"/>--> <!--need to change 25 class APIs-->
    <module name="InterfaceIsType"/> <!-- Interfaces must be types (not just constants) -->
    <module name="MutableException"/>
    <module name="OneTopLevelClass"/>
    <module name="ThrowsCount">
      <property name="max" value="5"/>
      <property name="ignorePrivateMethods" value="false"/>
    </module>

    <!-- Coding -->
    <module name="CovariantEquals"/>
    <!-- Require hash code override when equals is -->
    <module name="EqualsHashCode"/>
    <module name="IllegalInstantiation">
      <property name="classes" value="java.lang.Boolean"/>
    </module>
    <module name="IllegalThrows"/>
    <module name="MissingSwitchDefault"/>
    <module name="ModifiedControlVariable"/>
    <module name="MultipleVariableDeclarations"/>
    <module name="NestedForDepth"/>
    <module name="NestedIfDepth">
      <!-- TODO: reduce this number -->
      <property name="max" value="4"/>
    </module>
    <module name="NestedTryDepth">
      <property name="max" value="2"/>
    </module>
    <module name="OneStatementPerLine"/>
    <!--<module name="ParameterAssignment"/>-->
    <module name="ReturnCount">
      <!-- TODO: reduce these numbers -->
      <property name="max" value="9" />
      <property name="maxForVoid" value="9"/>
    </module>
    <module name="SimplifyBooleanExpression"/>
    <module name="SimplifyBooleanReturn"/>
    <module name="StringLiteralEquality"/>
    <module name="SuperFinalize"/>
    <module name="UnnecessaryParentheses"/>
    <!--<module name="VariableDeclarationUsageDistance"/>-->

    <!-- Imports -->
    <module name="AvoidStarImport">
      <property name="allowClassImports" value="false"/>
      <property name="allowStaticMemberImports" value="false"/>
    </module>
    <module name="RedundantImport"/>
    <!--
      Note: Import order is moved to Spotless. See ./gradlew spotlessCheck; ./gradlew spotlessApply
    <module name="UnusedImports"/>
    <module name="ImportOrder">
      <property name="groups" value="/^java\./,javax,org,net,com"/>
      <property name="ordered" value="true"/>
      <property name="separated" value="true"/>
      <property name="option" value="top"/>
     <property name="sortStaticImportsAlphabetically" value="true"/>
    </module>
    -->

    <!-- JavaDocs -->
<!--
    <module name="JavadocMethod">
      <property name="minLineCount" value="3"/>
      <property name="scope" value="protected"/>
      <property name="allowUndeclaredRTE" value="true"/>
      <property name="allowMissingThrowsTags" value="true"/>
      <property name="allowMissingPropertyJavadoc" value="true"/>
      <property name="ignoreMethodNamesRegex" value="(get|set|is).*"/>
      &lt;!&ndash; Only check methods, i.e. ignore constructors  &ndash;&gt;
      <property name="tokens" value="METHOD_DEF"/>
    </module>
    -->
    <!--<module name="NonEmptyAtclauseDescription"/>-->

    <!-- Misc -->
    <module name="ArrayTypeStyle"/>
    <module name="AvoidEscapedUnicodeCharacters"/>
    <!--<module name="CommentsIndentation"/>-->
    <module name="OuterTypeFilename"/>
    <module name="UpperEll"/>

    <!-- code metrics -->
    <!--<module name="BooleanExpressionComplexity"/>-->
    <!--<module name="ClassFanOutComplexity"/>-->
    <!--<module name="CyclomaticComplexity"/>-->
    <!--<module name="NPathComplexity"/>-->

    <!-- size -->
    <module name="AnonInnerLength">
      <property name="max" value="45"/>
    </module>

    <!-- whitespace -->
    <module name="EmptyForInitializerPad"/>
    <module name="EmptyForIteratorPad"/>
    <module name="MethodParamPad"/>
    <module name="NoLineWrap"/>
    <module name="TypecastParenPad"/>

    <!--
    Allow comment to suppress checkstyle for a single line
    e.g. // CHECKSTYLE IGNORE MagicNumber
    -->
    <module name="SuppressWithNearbyCommentFilter">
      <property name="commentFormat" value="CHECKSTYLE IGNORE (\w+)"/>
      <property name="checkFormat" value="$1"/>
    </module>
  </module>

  <module name="SuppressionFilter">
    <!-- config_loc is used by Eclipse plugin -->
    <property name="file" value="${config_loc}/checkstyle-suppressions.xml"/>
  </module>

</module>
