<?xml version="1.0"?>
<!--
~ Licensed 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"
        "https://checkstyle.org/dtds/configuration_1_3.dtd">

<!--
  Checkstyle configuration that checks the sun coding conventions from:

    - the Java Language Specification at
      http://java.sun.com/docs/books/jls/second_edition/html/index.html

    - the Sun Code Conventions at http://java.sun.com/docs/codeconv/

    - the Javadoc guidelines at
      http://java.sun.com/j2se/javadoc/writingdoccomments/index.html

    - the JDK Api documentation http://java.sun.com/j2se/docs/api/index.html

    - some best practices

  Checkstyle is very configurable. Be sure to read the documentation at
  http://checkstyle.sf.net (or in your downloaded distribution).

  Most Checks are configurable, be sure to consult the documentation.

  To completely disable a check, just comment it out or delete it from the file.

  Finally, it is worth reading the documentation.
-->

<module name="Checker">
    <property name="basedir" value="${root.dir}"/>

    <!-- Activation here is needed for IntelliJ CheckstyleIDEA plugin -->
    <module name="SuppressionFilter">
        <property name="file" value="${root.dir}/src/suppressions.xml"/>
    </module>

    <!-- Enable suppression of file contents using //CHECKSTYLE:[ON|OFF] comments -->
    <!--
    <module name="SuppressionCommentFilter"/>
    -->

    <!-- Enable the suppression annotation @SuppressWarnings("checkstyle:lowercasecheckname"} -->
    <module name="SuppressWarningsFilter"/>

    <!-- Checks that a package-info.java file exists for each package.     -->
    <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage -->
    <module name="JavadocPackage"/>

    <!-- Checks whether files end with a new line.                        -->
    <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
    <module name="NewlineAtEndOfFile">
        <property name="lineSeparator" value="system"/>
    </module>

    <!-- Checks that property files contain the same keys.         -->
    <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
    <module name="Translation"/>

    <!-- Checks for Size Violations.                    -->
    <!-- See http://checkstyle.sf.net/config_sizes.html -->
    <module name="FileLength">
        <property name="max" value="1500"/>
    </module>

    <!-- Checks for whitespace                               -->
    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
    <module name="FileTabCharacter"/>

    <!-- Miscellaneous other checks.                   -->
    <!-- See http://checkstyle.sf.net/config_misc.html -->
    <module name="RegexpSingleline">
        <property name="format" value="\s+$"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Line has trailing spaces."/>
    </module>

    <module name="LineLength">
        <property name="max" value="130"/>
    </module>

    <module name="TreeWalker">
        <!-- Needed for SuppressWarningsFilter to work -->
        <module name="SuppressWarningsHolder"/>

        <!-- Checks for Javadoc comments.                     -->
        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
        <!-- Only for methods on public APIs we agreed to have JavaDoc. -->
        <!-- TODO: figure out how to do that -->
        <!--<module name="JavadocMethod">-->
        <!--<property name="scope" value="public"/>-->
        <!--<property name="allowMissingParamTags" value="true"/>-->
        <!--</module>-->
        <module name="JavadocType">
            <property name="scope" value="public"/>
        </module>
        <module name="JavadocVariable">
            <property name="scope" value="public"/>
        </module>
        <module name="JavadocStyle">
            <property name="checkFirstSentence" value="false"/>
            <property name="checkHtml" value="false"/>
        </module>

        <module name="TrailingComment"/>

        <!-- Checks for Naming Conventions.                  -->
        <!-- See http://checkstyle.sf.net/config_naming.html -->
        <module name="ConstantName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <module name="StaticVariableName"/>
        <module name="TypeName"/>
        <module name="UpperEll"/>

        <!-- Checks for imports                              -->
        <!-- See http://checkstyle.sf.net/config_import.html -->
        <module name="AvoidStarImport">
            <property name="excludes" value="java.awt,javax.swing"/>
        </module>
        <!-- defaults to sun.* packages -->
        <module name="IllegalImport">
            <property name="illegalPkgs" value="sun,org.jetbrains.annotations"/>
        </module>
        <module name="RedundantImport"/>
        <module name="UnusedImports">
            <property name="processJavadoc" value="true"/>
        </module>

        <!-- Checks for Size Violations.                    -->
        <!-- See http://checkstyle.sf.net/config_sizes.html -->
        <module name="MethodLength">
            <property name="tokens" value="METHOD_DEF"/>
            <property name="max" value="60"/>
            <property name="countEmpty" value="false"/>
        </module>
        <module name="MethodLength">
            <property name="max" value="200"/>
            <property name="tokens" value="METHOD_DEF"/>
        </module>
        <module name="MethodLength">
            <property name="max" value="60"/>
            <property name="tokens" value="CTOR_DEF"/>
        </module>
        <module name="ParameterNumber">
            <property name="max" value="8"/>
            <property name="tokens" value="METHOD_DEF"/>
        </module>
        <module name="ParameterNumber">
            <property name="max" value="10"/>
            <property name="tokens" value="CTOR_DEF"/>
        </module>
        <module name="AnonInnerLength">
            <property name="max" value="30"/>
        </module>
        <module name="ExecutableStatementCount">
            <property name="max" value="20"/>
            <property name="tokens" value="CTOR_DEF, INSTANCE_INIT, STATIC_INIT"/>
        </module>
        <module name="OuterTypeNumber">
            <property name="max" value="2"/>
        </module>
        <module name="MethodCount">
            <property name="maxTotal" value="30"/>
        </module>

        <!-- Checks for whitespace                               -->
        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
        <!-- module name="EmptyForIteratorPad"/ -->
        <module name="GenericWhitespace"/>
        <module name="MethodParamPad"/>
        <!-- module name="NoWhitespaceAfter"/ -->
        <!-- module name="NoWhitespaceBefore"/ -->
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround"/>

        <!-- Modifier Checks                                    -->
        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
        <module name="ModifierOrder"/>
        <module name="RedundantModifier"/>

        <!-- Checks for blocks. You know, those {}'s         -->
        <!-- See http://checkstyle.sf.net/config_blocks.html -->
        <module name="AvoidNestedBlocks"/>
        <module name="EmptyBlock"/>
        <module name="LeftCurly"/>
        <module name="NeedBraces"/>
        <module name="RightCurly"/>

        <!-- Checks for common coding problems               -->
        <!-- See http://checkstyle.sf.net/config_coding.html -->
        <module name="CovariantEquals"/>
        <module name="DeclarationOrder"/>
        <module name="ExplicitInitialization"/>
        <module name="DefaultComesLast"/>
        <module name="FallThrough"/>
        <module name="MultipleVariableDeclarations"/>
        <module name="EmptyStatement"/>
        <!--<module name="HiddenField">-->
        <!--<property name="tokens" value="VARIABLE_DEF"/>-->
        <!--</module>-->
        <module name="IllegalInstantiation">
            <property name="classes" value="java.lang.Boolean"/>
        </module>
        <module name="IllegalTokenText">
            <property name="tokens" value="NUM_INT,NUM_LONG"/>
            <property name="format" value="^0[^lx]"/>
            <property name="ignoreCase" value="true"/>
        </module>
        <module name="IllegalType">
            <property name="ignoredMethodNames" value="getInstance"/>
            <property name="tokens" value="PARAMETER_DEF, METHOD_DEF"/>
        </module>
        <module name="InnerAssignment"/>
        <module name="ReturnCount">
            <property name="max" value="8"/>
            <property name="maxForVoid" value="8"/>
        </module>
        <module name="NestedIfDepth">
            <property name="max" value="2"/>
        </module>
        <module name="NestedTryDepth">
            <property name="max" value="2"/>
        </module>
        <module name="PackageDeclaration"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>
        <module name="StringLiteralEquality"/>
        <module name="SuperClone"/>
        <module name="SuperFinalize"/>
        <module name="MagicNumber">
            <property name="ignoreHashCodeMethod" value="true"/>
            <property name="ignoreAnnotation" value="true"/>
            <property name="ignoreNumbers" value="-1, 0, 1, 2, 3, 4, 5, 6"/>
            <property name="constantWaiverParentToken"
                      value="ASSIGN, ARRAY_INIT, EXPR, UNARY_PLUS, UNARY_MINUS, TYPECAST, ELIST, LITERAL_NEW,
                      METHOD_CALL, STAR, DIV, PLUS, MINUS, SL, QUESTION"/>
        </module>
        <module name="EqualsHashCode"/>
        <module name="IllegalInstantiation"/>
        <module name="MissingSwitchDefault"/>

        <!-- Checks for class design                         -->
        <!-- See http://checkstyle.sf.net/config_design.html -->
        <module name="FinalClass"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="InterfaceIsType"/>
        <module name="VisibilityModifier">
            <property name="packageAllowed" value="true"/>
            <property name="protectedAllowed" value="true"/>
        </module>

        <!-- Metrics -->
        <module name="BooleanExpressionComplexity">
            <property name="max" value="4"/>
        </module>
        <module name="ClassDataAbstractionCoupling">
            <property name="max" value="15"/>
        </module>
        <module name="ClassFanOutComplexity">
            <property name="max" value="40"/>
        </module>
        <module name="CyclomaticComplexity">
            <property name="severity" value="error"/>
            <property name="max" value="12"/>
        </module>
        <module name="NPathComplexity">
            <!-- TODO Agree on the value
                 Checkstyle 7.7 improved the NPath algorithm further that leads to higher NPath counts.
                 7.6 passes with max 50, 7.7 needs it to be set to at least 216
                 the default threshold is 200
            -->
            <property name="max" value="250"/>
        </module>

        <!-- Miscellaneous other checks.                   -->
        <!-- See http://checkstyle.sf.net/config_misc.html -->
        <module name="ArrayTypeStyle"/>
        <module name="UpperEll"/>

        <module name="RegexpSinglelineJava">
            <property name="id" value="no-parameterized-runner"/>
            <property name="format" value="RunWith\(Parameterized\.class\)"/>
            <property name="ignoreComments" value="true"/>
            <property name="message"
                      value="Please use com.hazelcast.test.HazelcastParametrizedRunner that correctly checks running member and client instances"/>
        </module>
    </module>
</module>
