////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2017 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.checks.coding;

import com.puppycrawl.tools.checkstyle.StatelessCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CheckUtils;
import com.puppycrawl.tools.checkstyle.utils.ScopeUtils;

/**
 * <p>
 * Checks if any class or object member explicitly initialized
 * to default for its type value ({@code null} for object
 * references, zero for numeric types and {@code char}
 * and {@code false} for {@code boolean}.
 * </p>
 * <p>
 * Rationale: each instance variable gets
 * initialized twice, to the same value.  Java
 * initializes each instance variable to its default
 * value (0 or null) before performing any
 * initialization specified in the code.  So in this case,
 * x gets initialized to 0 twice, and bar gets initialized
 * to null twice.  So there is a minor inefficiency.  This style of
 * coding is a hold-over from C/C++ style coding,
 * and it shows that the developer isn't really confident that
 * Java really initializes instance variables to default
 * values.
 * </p>
 *
 * @author o_sukhodolsky
 */
@StatelessCheck
public class ExplicitInitializationCheck extends AbstractCheck {

    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_KEY = "explicit.init";

    /** Whether only explicit initialization made to null should be checked.**/
    private boolean onlyObjectReferences;

    @Override
    public final int[] getDefaultTokens() {
        return new int[] {TokenTypes.VARIABLE_DEF};
    }

    @Override
    public final int[] getRequiredTokens() {
        return getDefaultTokens();
    }

    @Override
    public final int[] getAcceptableTokens() {
        return new int[] {TokenTypes.VARIABLE_DEF};
    }

    /**
     * Sets whether only explicit initialization made to null should be checked.
     * @param onlyObjectReferences whether only explicit initialization made to null
     *                             should be checked
     */
    public void setOnlyObjectReferences(boolean onlyObjectReferences) {
        this.onlyObjectReferences = onlyObjectReferences;
    }

    @Override
    public void visitToken(DetailAST ast) {
        if (!isSkipCase(ast)) {
            final DetailAST assign = ast.findFirstToken(TokenTypes.ASSIGN);
            final DetailAST exprStart =
                assign.getFirstChild().getFirstChild();
            final DetailAST type = ast.findFirstToken(TokenTypes.TYPE);
            if (isObjectType(type)
                && exprStart.getType() == TokenTypes.LITERAL_NULL) {
                final DetailAST ident = ast.findFirstToken(TokenTypes.IDENT);
                log(ident, MSG_KEY, ident.getText(), "null");
            }
            if (!onlyObjectReferences) {
                validateNonObjects(ast);
            }
        }
    }

    /**
     * Checks for explicit initializations made to 'false', '0' and '\0'.
     * @param ast token being checked for explicit initializations
     */
    private void validateNonObjects(DetailAST ast) {
        final DetailAST ident = ast.findFirstToken(TokenTypes.IDENT);
        final DetailAST assign = ast.findFirstToken(TokenTypes.ASSIGN);
        final DetailAST exprStart =
                assign.getFirstChild().getFirstChild();
        final DetailAST type = ast.findFirstToken(TokenTypes.TYPE);
        final int primitiveType = type.getFirstChild().getType();
        if (primitiveType == TokenTypes.LITERAL_BOOLEAN
                && exprStart.getType() == TokenTypes.LITERAL_FALSE) {
            log(ident, MSG_KEY, ident.getText(), "false");
        }
        if (isNumericType(primitiveType) && isZero(exprStart)) {
            log(ident, MSG_KEY, ident.getText(), "0");
        }
        if (primitiveType == TokenTypes.LITERAL_CHAR
                && isZeroChar(exprStart)) {
            log(ident, MSG_KEY, ident.getText(), "\\0");
        }
    }

    /**
     * Examine char literal for initializing to default value.
     * @param exprStart expression
     * @return true is literal is initialized by zero symbol
     */
    private static boolean isZeroChar(DetailAST exprStart) {
        return isZero(exprStart)
            || exprStart.getType() == TokenTypes.CHAR_LITERAL
            && "'\\0'".equals(exprStart.getText());
    }

    /**
     * Checks for cases that should be skipped: no assignment, local variable, final variables.
     * @param ast Variable def AST
     * @return true is that is a case that need to be skipped.
     */
    private static boolean isSkipCase(DetailAST ast) {
        boolean skipCase = true;

        // do not check local variables and
        // fields declared in interface/annotations
        if (!ScopeUtils.isLocalVariableDef(ast)
                && !ScopeUtils.isInInterfaceOrAnnotationBlock(ast)) {
            final DetailAST assign = ast.findFirstToken(TokenTypes.ASSIGN);

            if (assign != null) {
                final DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
                skipCase = modifiers.findFirstToken(TokenTypes.FINAL) != null;
            }
        }
        return skipCase;
    }

    /**
     * Determines if a given type is an object type.
     * @param type type to check.
     * @return true if it is an object type.
     */
    private static boolean isObjectType(DetailAST type) {
        final int objectType = type.getFirstChild().getType();
        return objectType == TokenTypes.IDENT || objectType == TokenTypes.DOT
                || objectType == TokenTypes.ARRAY_DECLARATOR;
    }

    /**
     * Determine if a given type is a numeric type.
     * @param type code of the type for check.
     * @return true if it's a numeric type.
     * @see TokenTypes
     */
    private static boolean isNumericType(int type) {
        return type == TokenTypes.LITERAL_BYTE
                || type == TokenTypes.LITERAL_SHORT
                || type == TokenTypes.LITERAL_INT
                || type == TokenTypes.LITERAL_FLOAT
                || type == TokenTypes.LITERAL_LONG
                || type == TokenTypes.LITERAL_DOUBLE;
    }

    /**
     * Checks if given node contains numeric constant for zero.
     *
     * @param expr node to check.
     * @return true if given node contains numeric constant for zero.
     */
    private static boolean isZero(DetailAST expr) {
        final int type = expr.getType();
        final boolean isZero;
        switch (type) {
            case TokenTypes.NUM_FLOAT:
            case TokenTypes.NUM_DOUBLE:
            case TokenTypes.NUM_INT:
            case TokenTypes.NUM_LONG:
                final String text = expr.getText();
                isZero = Double.compare(CheckUtils.parseDouble(text, type), 0.0) == 0;
                break;
            default:
                isZero = false;
        }
        return isZero;
    }
}
