////////////////////////////////////////////////////////////////////////////////
// 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 java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

/**
 * Checks that any combination of String literals
 * is on the left side of an equals() comparison.
 * Also checks for String literals assigned to some field
 * (such as {@code someString.equals(anotherString = "text")}).
 *
 * <p>Rationale: Calling the equals() method on String literals
 * will avoid a potential NullPointerException.  Also, it is
 * pretty common to see null check right before equals comparisons
 * which is not necessary in the below example.
 *
 * <p>For example:
 *
 * <pre>
 *  {@code
 *    String nullString = null;
 *    nullString.equals(&quot;My_Sweet_String&quot;);
 *  }
 * </pre>
 * should be refactored to
 *
 * <pre>
 *  {@code
 *    String nullString = null;
 *    &quot;My_Sweet_String&quot;.equals(nullString);
 *  }
 * </pre>
 *
 * @author Travis Schneeberger
 * @author Vladislav Lisetskiy
 */
@FileStatefulCheck
public class EqualsAvoidNullCheck extends AbstractCheck {

    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_EQUALS_AVOID_NULL = "equals.avoid.null";

    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_EQUALS_IGNORE_CASE_AVOID_NULL = "equalsIgnoreCase.avoid.null";

    /** Method name for comparison. */
    private static final String EQUALS = "equals";

    /** Type name for comparison. */
    private static final String STRING = "String";

    /** Whether to process equalsIgnoreCase() invocations. */
    private boolean ignoreEqualsIgnoreCase;

    /** Stack of sets of field names, one for each class of a set of nested classes. */
    private FieldFrame currentFrame;

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

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

    @Override
    public int[] getRequiredTokens() {
        return new int[] {
            TokenTypes.METHOD_CALL,
            TokenTypes.CLASS_DEF,
            TokenTypes.METHOD_DEF,
            TokenTypes.LITERAL_IF,
            TokenTypes.LITERAL_FOR,
            TokenTypes.LITERAL_WHILE,
            TokenTypes.LITERAL_DO,
            TokenTypes.LITERAL_CATCH,
            TokenTypes.LITERAL_TRY,
            TokenTypes.VARIABLE_DEF,
            TokenTypes.PARAMETER_DEF,
            TokenTypes.CTOR_DEF,
            TokenTypes.SLIST,
            TokenTypes.ENUM_DEF,
            TokenTypes.ENUM_CONSTANT_DEF,
            TokenTypes.LITERAL_NEW,
        };
    }

    /**
     * Whether to ignore checking {@code String.equalsIgnoreCase(String)}.
     * @param newValue whether to ignore checking
     *    {@code String.equalsIgnoreCase(String)}.
     */
    public void setIgnoreEqualsIgnoreCase(boolean newValue) {
        ignoreEqualsIgnoreCase = newValue;
    }

    @Override
    public void beginTree(DetailAST rootAST) {
        currentFrame = new FieldFrame(null);
    }

    @Override
    public void visitToken(final DetailAST ast) {
        switch (ast.getType()) {
            case TokenTypes.VARIABLE_DEF:
            case TokenTypes.PARAMETER_DEF:
                currentFrame.addField(ast);
                break;
            case TokenTypes.METHOD_CALL:
                processMethodCall(ast);
                break;
            case TokenTypes.SLIST:
                processSlist(ast);
                break;
            case TokenTypes.LITERAL_NEW:
                processLiteralNew(ast);
                break;
            default:
                processFrame(ast);
        }
    }

    @Override
    public void leaveToken(DetailAST ast) {
        final int astType = ast.getType();
        if (astType != TokenTypes.VARIABLE_DEF
                && astType != TokenTypes.PARAMETER_DEF
                && astType != TokenTypes.METHOD_CALL
                && astType != TokenTypes.SLIST
                && astType != TokenTypes.LITERAL_NEW
                || astType == TokenTypes.LITERAL_NEW
                    && ast.findFirstToken(TokenTypes.OBJBLOCK) != null) {
            currentFrame = currentFrame.getParent();
        }
        else if (astType == TokenTypes.SLIST) {
            leaveSlist(ast);
        }
    }

    @Override
    public void finishTree(DetailAST ast) {
        traverseFieldFrameTree(currentFrame);
    }

    /**
     * Determine whether SLIST begins static or non-static block and add it as
     * a frame in this case.
     * @param ast SLIST ast.
     */
    private void processSlist(DetailAST ast) {
        final int parentType = ast.getParent().getType();
        if (parentType == TokenTypes.SLIST
                || parentType == TokenTypes.STATIC_INIT
                || parentType == TokenTypes.INSTANCE_INIT) {
            final FieldFrame frame = new FieldFrame(currentFrame);
            currentFrame.addChild(frame);
            currentFrame = frame;
        }
    }

    /**
     * Determine whether SLIST begins static or non-static block.
     * @param ast SLIST ast.
     */
    private void leaveSlist(DetailAST ast) {
        final int parentType = ast.getParent().getType();
        if (parentType == TokenTypes.SLIST
                || parentType == TokenTypes.STATIC_INIT
                || parentType == TokenTypes.INSTANCE_INIT) {
            currentFrame = currentFrame.getParent();
        }
    }

    /**
     * Process CLASS_DEF, METHOD_DEF, LITERAL_IF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO,
     * LITERAL_CATCH, LITERAL_TRY, CTOR_DEF, ENUM_DEF, ENUM_CONSTANT_DEF.
     * @param ast processed ast.
     */
    private void processFrame(DetailAST ast) {
        final FieldFrame frame = new FieldFrame(currentFrame);
        final int astType = ast.getType();
        if (astType == TokenTypes.CLASS_DEF
                || astType == TokenTypes.ENUM_DEF
                || astType == TokenTypes.ENUM_CONSTANT_DEF) {
            frame.setClassOrEnumOrEnumConstDef(true);
            frame.setFrameName(ast.findFirstToken(TokenTypes.IDENT).getText());
        }
        currentFrame.addChild(frame);
        currentFrame = frame;
    }

    /**
     * Add the method call to the current frame if it should be processed.
     * @param methodCall METHOD_CALL ast.
     */
    private void processMethodCall(DetailAST methodCall) {
        final DetailAST dot = methodCall.getFirstChild();
        if (dot.getType() == TokenTypes.DOT) {
            final String methodName = dot.getLastChild().getText();
            if (EQUALS.equals(methodName)
                    || !ignoreEqualsIgnoreCase && "equalsIgnoreCase".equals(methodName)) {
                currentFrame.addMethodCall(methodCall);
            }
        }
    }

    /**
     * Determine whether LITERAL_NEW is an anonymous class definition and add it as
     * a frame in this case.
     * @param ast LITERAL_NEW ast.
     */
    private void processLiteralNew(DetailAST ast) {
        if (ast.findFirstToken(TokenTypes.OBJBLOCK) != null) {
            final FieldFrame frame = new FieldFrame(currentFrame);
            currentFrame.addChild(frame);
            currentFrame = frame;
        }
    }

    /**
     * Traverse the tree of the field frames to check all equals method calls.
     * @param frame to check method calls in.
     */
    private void traverseFieldFrameTree(FieldFrame frame) {
        for (FieldFrame child: frame.getChildren()) {
            if (!child.getChildren().isEmpty()) {
                traverseFieldFrameTree(child);
            }
            currentFrame = child;
            child.getMethodCalls().forEach(this::checkMethodCall);
        }
    }

    /**
     * Check whether the method call should be violated.
     * @param methodCall method call to check.
     */
    private void checkMethodCall(DetailAST methodCall) {
        DetailAST objCalledOn = methodCall.getFirstChild().getFirstChild();
        if (objCalledOn.getType() == TokenTypes.DOT) {
            objCalledOn = objCalledOn.getLastChild();
        }
        final DetailAST expr = methodCall.findFirstToken(TokenTypes.ELIST).getFirstChild();
        if (isObjectValid(objCalledOn)
                && containsOneArgument(methodCall)
                && containsAllSafeTokens(expr)
                && isCalledOnStringFieldOrVariable(objCalledOn)) {
            final String methodName = methodCall.getFirstChild().getLastChild().getText();
            if (EQUALS.equals(methodName)) {
                log(methodCall.getLineNo(), methodCall.getColumnNo(),
                    MSG_EQUALS_AVOID_NULL);
            }
            else {
                log(methodCall.getLineNo(), methodCall.getColumnNo(),
                    MSG_EQUALS_IGNORE_CASE_AVOID_NULL);
            }
        }
    }

    /**
     * Check whether the object equals method is called on is not a String literal
     * and not too complex.
     * @param objCalledOn the object equals method is called on ast.
     * @return true if the object is valid.
     */
    private static boolean isObjectValid(DetailAST objCalledOn) {
        boolean result = true;
        final DetailAST previousSibling = objCalledOn.getPreviousSibling();
        if (previousSibling != null
                && previousSibling.getType() == TokenTypes.DOT) {
            result = false;
        }
        if (isStringLiteral(objCalledOn)) {
            result = false;
        }
        return result;
    }

    /**
     * Checks for calling equals on String literal and
     * anon object which cannot be null.
     * @param objCalledOn object AST
     * @return if it is string literal
     */
    private static boolean isStringLiteral(DetailAST objCalledOn) {
        return objCalledOn.getType() == TokenTypes.STRING_LITERAL
                || objCalledOn.getType() == TokenTypes.LITERAL_NEW;
    }

    /**
     * Verify that method call has one argument.
     *
     * @param methodCall METHOD_CALL DetailAST
     * @return true if method call has one argument.
     */
    private static boolean containsOneArgument(DetailAST methodCall) {
        final DetailAST elist = methodCall.findFirstToken(TokenTypes.ELIST);
        return elist.getChildCount() == 1;
    }

    /**
     * Looks for all "safe" Token combinations in the argument
     * expression branch.
     * @param expr the argument expression
     * @return - true if any child matches the set of tokens, false if not
     */
    private static boolean containsAllSafeTokens(final DetailAST expr) {
        DetailAST arg = expr.getFirstChild();
        arg = skipVariableAssign(arg);

        boolean argIsNotNull = false;
        if (arg.getType() == TokenTypes.PLUS) {
            DetailAST child = arg.getFirstChild();
            while (child != null
                    && !argIsNotNull) {
                argIsNotNull = child.getType() == TokenTypes.STRING_LITERAL
                        || child.getType() == TokenTypes.IDENT;
                child = child.getNextSibling();
            }
        }

        return argIsNotNull
                || !arg.branchContains(TokenTypes.IDENT)
                    && !arg.branchContains(TokenTypes.LITERAL_NULL);
    }

    /**
     * Skips over an inner assign portion of an argument expression.
     * @param currentAST current token in the argument expression
     * @return the next relevant token
     */
    private static DetailAST skipVariableAssign(final DetailAST currentAST) {
        DetailAST result = currentAST;
        if (currentAST.getType() == TokenTypes.ASSIGN
                && currentAST.getFirstChild().getType() == TokenTypes.IDENT) {
            result = currentAST.getFirstChild().getNextSibling();
        }
        return result;
    }

    /**
     * Determine, whether equals method is called on a field of String type.
     * @param objCalledOn object ast.
     * @return true if the object is of String type.
     */
    private boolean isCalledOnStringFieldOrVariable(DetailAST objCalledOn) {
        final boolean result;
        final DetailAST previousSiblingAst = objCalledOn.getPreviousSibling();
        if (previousSiblingAst == null) {
            result = isStringFieldOrVariable(objCalledOn);
        }
        else {
            if (previousSiblingAst.getType() == TokenTypes.LITERAL_THIS) {
                result = isStringFieldOrVariableFromThisInstance(objCalledOn);
            }
            else {
                final String className = previousSiblingAst.getText();
                result = isStringFieldOrVariableFromClass(objCalledOn, className);
            }
        }
        return result;
    }

    /**
     * Whether the field or the variable is of String type.
     * @param objCalledOn the field or the variable to check.
     * @return true if the field or the variable is of String type.
     */
    private boolean isStringFieldOrVariable(DetailAST objCalledOn) {
        boolean result = false;
        final String name = objCalledOn.getText();
        FieldFrame frame = currentFrame;
        while (frame != null) {
            final DetailAST field = frame.findField(name);
            if (field != null
                    && (frame.isClassOrEnumOrEnumConstDef()
                            || checkLineNo(field, objCalledOn))) {
                result = STRING.equals(getFieldType(field));
                break;
            }
            frame = frame.getParent();
        }
        return result;
    }

    /**
     * Whether the field or the variable from THIS instance is of String type.
     * @param objCalledOn the field or the variable from THIS instance to check.
     * @return true if the field or the variable from THIS instance is of String type.
     */
    private boolean isStringFieldOrVariableFromThisInstance(DetailAST objCalledOn) {
        boolean result = false;
        final String name = objCalledOn.getText();
        final DetailAST field = getObjectFrame(currentFrame).findField(name);
        if (field != null) {
            result = STRING.equals(getFieldType(field));
        }
        return result;
    }

    /**
     * Whether the field or the variable from the specified class is of String type.
     * @param objCalledOn the field or the variable from the specified class to check.
     * @param className the name of the class to check in.
     * @return true if the field or the variable from the specified class is of String type.
     */
    private boolean isStringFieldOrVariableFromClass(DetailAST objCalledOn,
            final String className) {
        boolean result = false;
        final String name = objCalledOn.getText();
        FieldFrame frame = getObjectFrame(currentFrame);
        while (frame != null) {
            if (className.equals(frame.getFrameName())) {
                final DetailAST field = frame.findField(name);
                if (field != null) {
                    result = STRING.equals(getFieldType(field));
                }
                break;
            }
            frame = getObjectFrame(frame.getParent());
        }
        return result;
    }

    /**
     * Get the nearest parent frame which is CLASS_DEF, ENUM_DEF or ENUM_CONST_DEF.
     * @param frame to start the search from.
     * @return the nearest parent frame which is CLASS_DEF, ENUM_DEF or ENUM_CONST_DEF.
     */
    private static FieldFrame getObjectFrame(FieldFrame frame) {
        FieldFrame objectFrame = frame;
        while (objectFrame != null && !objectFrame.isClassOrEnumOrEnumConstDef()) {
            objectFrame = objectFrame.getParent();
        }
        return objectFrame;
    }

    /**
     * Check whether the field is declared before the method call in case of
     * methods and initialization blocks.
     * @param field field to check.
     * @param objCalledOn object equals method called on.
     * @return true if the field is declared before the method call.
     */
    private static boolean checkLineNo(DetailAST field, DetailAST objCalledOn) {
        boolean result = false;
        // Required for pitest coverage. We should specify columnNo passing condition
        // in such a way, so that the minimal possible distance between field and
        // objCalledOn will be the maximal condition to pass this check.
        // The minimal distance between objCalledOn and field (of type String) initialization
        // is calculated as follows:
        // String(6) + space(1) + variableName(1) + assign(1) +
        // anotherStringVariableName(1) + semicolon(1) = 11
        // Example: length of "String s=d;" is 11 symbols.
        final int minimumSymbolsBetween = 11;
        if (field.getLineNo() < objCalledOn.getLineNo()
                || field.getLineNo() == objCalledOn.getLineNo()
                    && field.getColumnNo() + minimumSymbolsBetween <= objCalledOn.getColumnNo()) {
            result = true;
        }
        return result;
    }

    /**
     * Get field type.
     * @param field to get the type from.
     * @return type of the field.
     */
    private static String getFieldType(DetailAST field) {
        String fieldType = null;
        final DetailAST identAst = field.findFirstToken(TokenTypes.TYPE)
                .findFirstToken(TokenTypes.IDENT);
        if (identAst != null) {
            fieldType = identAst.getText();
        }
        return fieldType;
    }

    /**
     * Holds the names of fields of a type.
     */
    private static class FieldFrame {
        /** Parent frame. */
        private final FieldFrame parent;

        /** Set of frame's children. */
        private final Set<FieldFrame> children = new HashSet<>();

        /** Set of fields. */
        private final Set<DetailAST> fields = new HashSet<>();

        /** Set of equals calls. */
        private final Set<DetailAST> methodCalls = new HashSet<>();

        /** Name of the class, enum or enum constant declaration. */
        private String frameName;

        /** Whether the frame is CLASS_DEF, ENUM_DEF or ENUM_CONST_DEF. */
        private boolean classOrEnumOrEnumConstDef;

        /**
         * Creates new frame.
         * @param parent parent frame.
         */
        FieldFrame(FieldFrame parent) {
            this.parent = parent;
        }

        /**
         * Set the frame name.
         * @param frameName value to set.
         */
        public void setFrameName(String frameName) {
            this.frameName = frameName;
        }

        /**
         * Getter for the frame name.
         * @return frame name.
         */
        public String getFrameName() {
            return frameName;
        }

        /**
         * Getter for the parent frame.
         * @return parent frame.
         */
        public FieldFrame getParent() {
            return parent;
        }

        /**
         * Getter for frame's children.
         * @return children of this frame.
         */
        public Set<FieldFrame> getChildren() {
            return Collections.unmodifiableSet(children);
        }

        /**
         * Add child frame to this frame.
         * @param child frame to add.
         */
        public void addChild(FieldFrame child) {
            children.add(child);
        }

        /**
         * Add field to this FieldFrame.
         * @param field the ast of the field.
         */
        public void addField(DetailAST field) {
            fields.add(field);
        }

        /**
         * Sets isClassOrEnum.
         * @param value value to set.
         */
        public void setClassOrEnumOrEnumConstDef(boolean value) {
            classOrEnumOrEnumConstDef = value;
        }

        /**
         * Getter for classOrEnumOrEnumConstDef.
         * @return classOrEnumOrEnumConstDef.
         */
        public boolean isClassOrEnumOrEnumConstDef() {
            return classOrEnumOrEnumConstDef;
        }

        /**
         * Add method call to this frame.
         * @param methodCall METHOD_CALL ast.
         */
        public void addMethodCall(DetailAST methodCall) {
            methodCalls.add(methodCall);
        }

        /**
         * Determines whether this FieldFrame contains the field.
         * @param name name of the field to check.
         * @return true if this FieldFrame contains instance field field.
         */
        public DetailAST findField(String name) {
            DetailAST resultField = null;
            for (DetailAST field: fields) {
                if (getFieldName(field).equals(name)) {
                    resultField = field;
                    break;
                }
            }
            return resultField;
        }

        /**
         * Getter for frame's method calls.
         * @return method calls of this frame.
         */
        public Set<DetailAST> getMethodCalls() {
            return Collections.unmodifiableSet(methodCalls);
        }

        /**
         * Get the name of the field.
         * @param field to get the name from.
         * @return name of the field.
         */
        private static String getFieldName(DetailAST field) {
            return field.findFirstToken(TokenTypes.IDENT).getText();
        }
    }
}
