////////////////////////////////////////////////////////////////////////////////
// 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.annotation;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

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.TextBlock;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagInfo;
import com.puppycrawl.tools.checkstyle.utils.AnnotationUtility;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;

/**
 * <p>
 * This class is used to verify that both the
 * {@link Deprecated Deprecated} annotation
 * and the deprecated javadoc tag are present when
 * either one is present.
 * </p>
 *
 * <p>
 * Both ways of flagging deprecation serve their own purpose.  The
 * {@link Deprecated Deprecated} annotation is used for
 * compilers and development tools.  The deprecated javadoc tag is
 * used to document why something is deprecated and what, if any,
 * alternatives exist.
 * </p>
 *
 * <p>
 * In order to properly mark something as deprecated both forms of
 * deprecation should be present.
 * </p>
 *
 * <p>
 * Package deprecation is a exception to the rule of always using the
 * javadoc tag and annotation to deprecate.  Only the package-info.java
 * file can contain a Deprecated annotation and it CANNOT contain
 * a deprecated javadoc tag.  This is the case with
 * Sun's javadoc tool released with JDK 1.6.0_11.  As a result, this check
 * does not deal with Deprecated packages in any way.  <b>No official
 * documentation was found confirming this behavior is correct
 * (of the javadoc tool).</b>
 * </p>
 *
 * <p>
 * To configure this check do the following:
 * </p>
 *
 * <pre>
 * &lt;module name="JavadocDeprecated"/&gt;
 * </pre>
 *
 * <p>
 * In addition you can configure this check with skipNoJavadoc
 * option to allow it to ignore cases when JavaDoc is missing,
 * but still warns when JavaDoc is present but either
 * {@link Deprecated Deprecated} is missing from JavaDoc or
 * {@link Deprecated Deprecated} is missing from the element.
 * To configure this check to allow it use:
 * </p>
 *
 * <pre>   &lt;property name="skipNoJavadoc" value="true" /&gt;</pre>
 *
 * <p>Examples of validating source code with skipNoJavadoc:</p>
 *
 * <pre>
 * <code>
 * {@literal @}deprecated
 * public static final int MY_CONST = 123456; // no violation
 *
 * &#47;** This javadoc is missing deprecated tag. *&#47;
 * {@literal @}deprecated
 * public static final int COUNTER = 10; // violation as javadoc exists
 * </code>
 * </pre>
 *
 * @author Travis Schneeberger
 */
@StatelessCheck
public final class MissingDeprecatedCheck extends AbstractCheck {
    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_KEY_ANNOTATION_MISSING_DEPRECATED =
            "annotation.missing.deprecated";

    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_KEY_JAVADOC_DUPLICATE_TAG =
            "javadoc.duplicateTag";

    /**
     * A key is pointing to the warning message text in "messages.properties"
     * file.
     */
    public static final String MSG_KEY_JAVADOC_MISSING = "javadoc.missing";

    /** {@link Deprecated Deprecated} annotation name. */
    private static final String DEPRECATED = "Deprecated";

    /** Fully-qualified {@link Deprecated Deprecated} annotation name. */
    private static final String FQ_DEPRECATED = "java.lang." + DEPRECATED;

    /** Compiled regexp to match Javadoc tag with no argument. */
    private static final Pattern MATCH_DEPRECATED =
            CommonUtils.createPattern("@(deprecated)\\s+\\S");

    /** Compiled regexp to match first part of multilineJavadoc tags. */
    private static final Pattern MATCH_DEPRECATED_MULTILINE_START =
            CommonUtils.createPattern("@(deprecated)\\s*$");

    /** Compiled regexp to look for a continuation of the comment. */
    private static final Pattern MATCH_DEPRECATED_MULTILINE_CONT =
            CommonUtils.createPattern("(\\*/|@|[^\\s\\*])");

    /** Multiline finished at end of comment. */
    private static final String END_JAVADOC = "*/";
    /** Multiline finished at next Javadoc. */
    private static final String NEXT_TAG = "@";

    /** Is deprecated element valid without javadoc. */
    private boolean skipNoJavadoc;

    /**
     * Set skipJavadoc value.
     * @param skipNoJavadoc user's value of skipJavadoc
     */
    public void setSkipNoJavadoc(boolean skipNoJavadoc) {
        this.skipNoJavadoc = skipNoJavadoc;
    }

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

    @Override
    public int[] getAcceptableTokens() {
        return new int[] {
            TokenTypes.INTERFACE_DEF,
            TokenTypes.CLASS_DEF,
            TokenTypes.ANNOTATION_DEF,
            TokenTypes.ENUM_DEF,
            TokenTypes.METHOD_DEF,
            TokenTypes.CTOR_DEF,
            TokenTypes.VARIABLE_DEF,
            TokenTypes.ENUM_CONSTANT_DEF,
            TokenTypes.ANNOTATION_FIELD_DEF,
        };
    }

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

    @Override
    public void visitToken(final DetailAST ast) {
        final TextBlock javadoc =
            getFileContents().getJavadocBefore(ast.getLineNo());

        final boolean containsAnnotation =
            AnnotationUtility.containsAnnotation(ast, DEPRECATED)
            || AnnotationUtility.containsAnnotation(ast, FQ_DEPRECATED);

        final boolean containsJavadocTag = containsJavadocTag(javadoc);

        if (containsAnnotation ^ containsJavadocTag && !(skipNoJavadoc && javadoc == null)) {
            log(ast.getLineNo(), MSG_KEY_ANNOTATION_MISSING_DEPRECATED);
        }
    }

    /**
     * Checks to see if the text block contains a deprecated tag.
     *
     * @param javadoc the javadoc of the AST
     * @return true if contains the tag
     */
    private boolean containsJavadocTag(final TextBlock javadoc) {
        boolean found = false;
        if (javadoc != null) {
            final String[] lines = javadoc.getText();
            int currentLine = javadoc.getStartLineNo() - 1;

            for (int i = 0; i < lines.length; i++) {
                currentLine++;
                final String line = lines[i];

                final Matcher javadocNoArgMatcher = MATCH_DEPRECATED.matcher(line);
                final Matcher noArgMultilineStart = MATCH_DEPRECATED_MULTILINE_START.matcher(line);

                if (javadocNoArgMatcher.find()) {
                    if (found) {
                        log(currentLine, MSG_KEY_JAVADOC_DUPLICATE_TAG,
                                JavadocTagInfo.DEPRECATED.getText());
                    }
                    found = true;
                }
                else if (noArgMultilineStart.find()) {
                    found = checkTagAtTheRestOfComment(lines, found, currentLine, i);
                }
            }
        }
        return found;
    }

    /**
     * Look for the rest of the comment if all we saw was
     * the tag and the name. Stop when we see '*' (end of
     * Javadoc), '{@literal @}' (start of next tag), or anything that's
     *  not whitespace or '*' characters.
     * @param lines all lines
     * @param foundBefore flag from parent method
     * @param currentLine current line
     * @param index som index
     * @return true if Tag is found
     */
    private boolean checkTagAtTheRestOfComment(String[] lines, boolean foundBefore,
            int currentLine, int index) {

        boolean found = false;
        int reindex = index + 1;
        while (reindex <= lines.length - 1) {
            final Matcher multilineCont = MATCH_DEPRECATED_MULTILINE_CONT.matcher(lines[reindex]);

            if (multilineCont.find()) {
                reindex = lines.length;
                final String lFin = multilineCont.group(1);
                if (lFin.equals(NEXT_TAG) || lFin.equals(END_JAVADOC)) {
                    log(currentLine, MSG_KEY_JAVADOC_MISSING);
                    if (foundBefore) {
                        log(currentLine, MSG_KEY_JAVADOC_DUPLICATE_TAG,
                                JavadocTagInfo.DEPRECATED.getText());
                    }
                    found = true;
                }
                else {
                    if (foundBefore) {
                        log(currentLine, MSG_KEY_JAVADOC_DUPLICATE_TAG,
                                JavadocTagInfo.DEPRECATED.getText());
                    }
                    found = true;
                }
            }
            reindex++;
        }
        return found;
    }
}
