<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright (c) 2016, 2020 Oracle and/or its affiliates.

    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" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--
    This file is based on maven-checkstyle-plugin config/sun_checks.xml file.
    Checkstyle configuration that checks the coding conventions based on:
      - 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 custom relaxations of the rules above & 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">

    <!--
        exclude files
         1. module-info.java - checkstyle can't process it
         2. ProxyFactory.java - sources copied from Weld, does not adhere to Helidon style
    -->
    <module name="BeforeExecutionExclusionFileFilter">
        <property name="fileNamePattern" value="module\-info\.java$|ProxyFactory\.java$"/>
    </module>

    <!--
        If you set the basedir property below, then all reported file
        names will be relative to the specified directory. See
        http://checkstyle.sourceforge.net/5.x/config.html#Checker
        <property name="basedir" value="${basedir}"/>
    -->
    <property name="charset" value="UTF-8"/>

    <!-- Checks that each Java package has a Javadoc file used for commenting. -->
    <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocPackage       -->
    <module name="JavadocPackage" />

    <!-- Checks to see if a file contains a tab character. -->
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>

    <!--
     Making sure we do not have @author tags in javadocs
     There is a list of developers in pom.xml that is sufficient for our needs.
     See https://github.com/checkstyle/checkstyle/issues/5339
    -->
    <module name="RegexpSingleline">
        <!-- The '.' in id is needed, otherwise ArrayIndexOutOfBounds happens -->
        <property name="id" value="Javadoc.javadocNoAuthor"/>
        <property name="format" value="^\s*\*\s*@author"/>
        <property name="minimum" value="0"/>
        <property name="maximum" value="0"/>
        <property name="message" value="Javadoc has illegal ''author'' tag."/>
        <property name="fileExtensions" value="java"/>
    </module>

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

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

    <module name="FileLength"/>

    <module name="SuppressWarningsFilter" />

    <!-- Checks for Size Violations.                    -->
    <!-- See http://checkstyle.sf.net/config_sizes.html -->
    <module name="LineLength">
        <property name="max" value="130"/>
        <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|@see| \* |@link|imp|@todo|@version|^Args=|.*--initialize-at-build-time|^javax.sql.DataSource"/>
    </module>

    <module name="TreeWalker">

        <module name="SuppressionCommentFilter">
            <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
            <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
            <property name="checkFormat" value="$1"/>
        </module>
        <module name="SuppressWarningsHolder" />

        <!-- Checks for Javadoc comments.                     -->
        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
        <module name="JavadocMethod">
            <property name="scope" value="protected"/>
            <property name="validateThrows" value="false"/>
        </module>
        <module name="MissingJavadocMethod">
            <property name="allowMissingPropertyJavadoc" value="true"/>
        </module>
        <module name="JavadocType">
            <property name="scope" value="protected"/>
        </module>
        <module name="JavadocVariable">
            <property name="scope" value="protected"/>
        </module>
        <module name="JavadocStyle"/>

        <!-- 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"/>

        <!-- Checks for imports                              -->
        <!-- See http://checkstyle.sf.net/config_import.html -->
        <module name="AvoidStarImport"/>
        <module name="UnusedImports"/>
        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
        <module name="RedundantImport"/>
        <module name="ImportOrder">
            <property name="groups" value="java, javax, io.helidon"/>
            <property name="ordered" value="true"/>
            <property name="separated" value="true"/>
            <property name="option" value="bottom"/>
            <property name="sortStaticImportsAlphabetically" value="true"/>
        </module>

        <!-- Checks for blocks. You know, those {}'s         -->
        <!-- See http://checkstyle.sf.net/config_blocks.html -->
        <module name="AvoidNestedBlocks"/>
        <module name="EmptyBlock">
            <property name="option" value="TEXT"/>
            <property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
        </module>
        <module name="NeedBraces">
            <property name="allowSingleLineStatement" value="true"/>
        </module>
        <module name="LeftCurly"/>
        <module name="RightCurly"/>
        <module name="RightCurly">
            <property name="option" value="alone"/>
            <property name="tokens"
                    value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT, INSTANCE_INIT"/>
        </module>

        <!-- Indentation -->
        <property name="tabWidth" value="4"/>

        <!-- Wrapping Lines -->
        <module name="NoLineWrap"/>
        <module name="SeparatorWrap">
            <property name="tokens" value="DOT"/>
            <property name="option" value="nl"/>
        </module>
        <module name="SeparatorWrap">
            <property name="tokens" value="COMMA"/>
            <property name="option" value="EOL"/>
        </module>

        <module name="MethodLength"/>

        <!-- Some Netty interfaces need this -->
        <module name="ParameterNumber">
            <property name="ignoreOverriddenMethods" value="true"/>
            <property name="tokens" value="METHOD_DEF"/>
        </module>

        <!-- Several variable declaration on one line: int i, p; -->
        <module name="MultipleVariableDeclarations"/>

        <module name="OuterTypeFilename"/>
        <module name="OneTopLevelClass"/>

        <!-- Checks for whitespace                               -->
        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
        <module name="EmptyForIteratorPad"/>
        <module name="OperatorWrap"/>
        <module name="WhitespaceAfter"/>
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter"/>
        <module name="NoWhitespaceBefore"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround">
            <!-- Removed static initializer issues: RCURLY, SLIST -->
            <property name="tokens"
                    value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV,
                            DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO,
                            LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH,
                            LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
                            NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN,
                            TYPE_EXTENSION_AND"/>
            <property name="allowEmptyConstructors" value="true"/>
            <property name="allowEmptyMethods" value="true"/>
            <property name="allowEmptyTypes" value="true"/>
            <property name="allowEmptyLoops" value="true"/>
            <message key="ws.notFollowed"
                    value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
            <message key="ws.notPreceded"
                    value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
        </module>

        <module name="GenericWhitespace">
            <message key="ws.followed"
                    value="GenericWhitespace ''{0}'' is followed by whitespace."/>
            <message key="ws.preceded"
                    value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
            <message key="ws.illegalFollow"
                    value="GenericWhitespace ''{0}'' should followed by whitespace."/>
            <message key="ws.notPreceded"
                    value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
        </module>

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

        <!-- Checks for common coding problems               -->
        <!-- See http://checkstyle.sf.net/config_coding.html -->
        <!-- module name="AvoidInlineConditionals"/-->
        <module name="EmptyStatement"/>
        <module name="EqualsHashCode"/>
        <!--<module name="HiddenField">-->
        <!--<property name="ignoreConstructorParameter" value="true"/>-->
        <!--<property name="ignoreSetter" value="true"/>-->
        <!--</module>-->
        <module name="IllegalInstantiation"/>
        <module name="InnerAssignment"/>
        <!--<module name="MagicNumber">-->
        <!--<property name="ignoreHashCodeMethod" value="true"/>-->
        <!--<property name="ignoreFieldDeclaration" value="true"/>-->
        <!--</module>-->
        <module name="MissingSwitchDefault"/>

        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>

        <!-- Checks for class design                         -->
        <!-- See http://checkstyle.sf.net/config_design.html -->
        <!-- Let's discuss this, I don't really like it: -->
        <!--<module name="DesignForExtension"/>-->
        <module name="HideUtilityClassConstructor"/>
        <module name="InterfaceIsType"/>
        <module name="VisibilityModifier"/>
        <module name="ThrowsCount">
            <property name="max" value="3"/>
        </module>

        <!-- Miscellaneous other checks.                   -->
        <!-- See http://checkstyle.sf.net/config_misc.html -->
        <module name="ArrayTypeStyle"/>
        <module name="TodoComment">
            <!-- TODO - we should add this configuration to remove todos from code -->
            <!-- <property name="format" value="(TODO)|(FIXME)|(EDIT)"/>-->
        </module>
        <module name="UpperEll"/>

        <module name="OneStatementPerLine"/>
        <module name="FallThrough"/>

        <module name="NoFinalizer"/>

        <module name="AnnotationLocation">
            <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
        </module>
        <module name="AnnotationLocation">
            <property name="tokens" value="VARIABLE_DEF"/>
            <property name="allowSamelineMultipleAnnotations" value="true"/>
        </module>

        <!-- No Trailing Whitespaces. -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="[ ]+$"/>
            <property name="message" value="File contains trailing whitespace."/>
        </module>
    </module>
</module>
