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

import antlr.collections.AST;
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.FullIdent;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;

/**
 * <p>
 * Checks for illegal instantiations where a factory method is preferred.
 * </p>
 * <p>
 * Rationale: Depending on the project, for some classes it might be
 * preferable to create instances through factory methods rather than
 * calling the constructor.
 * </p>
 * <p>
 * A simple example is the java.lang.Boolean class, to save memory and CPU
 * cycles it is preferable to use the predefined constants TRUE and FALSE.
 * Constructor invocations should be replaced by calls to Boolean.valueOf().
 * </p>
 * <p>
 * Some extremely performance sensitive projects may require the use of factory
 * methods for other classes as well, to enforce the usage of number caches or
 * object pools.
 * </p>
 * <p>
 * Limitations: It is currently not possible to specify array classes.
 * </p>
 * <p>
 * An example of how to configure the check is:
 * </p>
 * <pre>
 * &lt;module name="IllegalInstantiation"/&gt;
 * </pre>
 * @author lkuehne
 */
@FileStatefulCheck
public class IllegalInstantiationCheck
    extends AbstractCheck {

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

    /** {@link java.lang} package as string. */
    private static final String JAVA_LANG = "java.lang.";

    /** The imports for the file. */
    private final Set<FullIdent> imports = new HashSet<>();

    /** The class names defined in the file. */
    private final Set<String> classNames = new HashSet<>();

    /** The instantiations in the file. */
    private final Set<DetailAST> instantiations = new HashSet<>();

    /** Set of fully qualified class names. E.g. "java.lang.Boolean" */
    private Set<String> illegalClasses = new HashSet<>();

    /** Name of the package. */
    private String pkgName;

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

    @Override
    public int[] getAcceptableTokens() {
        return new int[] {
            TokenTypes.IMPORT,
            TokenTypes.LITERAL_NEW,
            TokenTypes.PACKAGE_DEF,
            TokenTypes.CLASS_DEF,
        };
    }

    @Override
    public int[] getRequiredTokens() {
        return new int[] {
            TokenTypes.IMPORT,
            TokenTypes.LITERAL_NEW,
            TokenTypes.PACKAGE_DEF,
        };
    }

    @Override
    public void beginTree(DetailAST rootAST) {
        pkgName = null;
        imports.clear();
        instantiations.clear();
        classNames.clear();
    }

    @Override
    public void visitToken(DetailAST ast) {
        switch (ast.getType()) {
            case TokenTypes.LITERAL_NEW:
                processLiteralNew(ast);
                break;
            case TokenTypes.PACKAGE_DEF:
                processPackageDef(ast);
                break;
            case TokenTypes.IMPORT:
                processImport(ast);
                break;
            case TokenTypes.CLASS_DEF:
                processClassDef(ast);
                break;
            default:
                throw new IllegalArgumentException("Unknown type " + ast);
        }
    }

    @Override
    public void finishTree(DetailAST rootAST) {
        instantiations.forEach(this::postProcessLiteralNew);
    }

    /**
     * Collects classes defined in the source file. Required
     * to avoid false alarms for local vs. java.lang classes.
     *
     * @param ast the class def token.
     */
    private void processClassDef(DetailAST ast) {
        final DetailAST identToken = ast.findFirstToken(TokenTypes.IDENT);
        final String className = identToken.getText();
        classNames.add(className);
    }

    /**
     * Perform processing for an import token.
     * @param ast the import token
     */
    private void processImport(DetailAST ast) {
        final FullIdent name = FullIdent.createFullIdentBelow(ast);
        // Note: different from UnusedImportsCheck.processImport(),
        // '.*' imports are also added here
        imports.add(name);
    }

    /**
     * Perform processing for an package token.
     * @param ast the package token
     */
    private void processPackageDef(DetailAST ast) {
        final DetailAST packageNameAST = ast.getLastChild()
                .getPreviousSibling();
        final FullIdent packageIdent =
                FullIdent.createFullIdent(packageNameAST);
        pkgName = packageIdent.getText();
    }

    /**
     * Collects a "new" token.
     * @param ast the "new" token
     */
    private void processLiteralNew(DetailAST ast) {
        if (ast.getParent().getType() != TokenTypes.METHOD_REF) {
            instantiations.add(ast);
        }
    }

    /**
     * Processes one of the collected "new" tokens when walking tree
     * has finished.
     * @param newTokenAst the "new" token.
     */
    private void postProcessLiteralNew(DetailAST newTokenAst) {
        final DetailAST typeNameAst = newTokenAst.getFirstChild();
        final AST nameSibling = typeNameAst.getNextSibling();
        if (nameSibling.getType() != TokenTypes.ARRAY_DECLARATOR) {
            // ast != "new Boolean[]"
            final FullIdent typeIdent = FullIdent.createFullIdent(typeNameAst);
            final String typeName = typeIdent.getText();
            final String fqClassName = getIllegalInstantiation(typeName);
            if (fqClassName != null) {
                final int lineNo = newTokenAst.getLineNo();
                final int colNo = newTokenAst.getColumnNo();
                log(lineNo, colNo, MSG_KEY, fqClassName);
            }
        }
    }

    /**
     * Checks illegal instantiations.
     * @param className instantiated class, may or may not be qualified
     * @return the fully qualified class name of className
     *     or null if instantiation of className is OK
     */
    private String getIllegalInstantiation(String className) {
        String fullClassName = null;

        if (illegalClasses.contains(className)) {
            fullClassName = className;
        }
        else {
            final int pkgNameLen;

            if (pkgName == null) {
                pkgNameLen = 0;
            }
            else {
                pkgNameLen = pkgName.length();
            }

            for (String illegal : illegalClasses) {
                if (isStandardClass(className, illegal)
                        || isSamePackage(className, pkgNameLen, illegal)) {
                    fullClassName = illegal;
                }
                else {
                    fullClassName = checkImportStatements(className);
                }

                if (fullClassName != null) {
                    break;
                }
            }
        }
        return fullClassName;
    }

    /**
     * Check import statements.
     * @param className name of the class
     * @return value of illegal instantiated type
     */
    private String checkImportStatements(String className) {
        String illegalType = null;
        // import statements
        for (FullIdent importLineText : imports) {
            String importArg = importLineText.getText();
            if (importArg.endsWith(".*")) {
                importArg = importArg.substring(0, importArg.length() - 1)
                        + className;
            }
            if (CommonUtils.baseClassName(importArg).equals(className)
                    && illegalClasses.contains(importArg)) {
                illegalType = importArg;
                break;
            }
        }
        return illegalType;
    }

    /**
     * Check that type is of the same package.
     * @param className class name
     * @param pkgNameLen package name
     * @param illegal illegal value
     * @return true if type of the same package
     */
    private boolean isSamePackage(String className, int pkgNameLen, String illegal) {
        // class from same package

        // the top level package (pkgName == null) is covered by the
        // "illegalInstances.contains(className)" check above

        // the test is the "no garbage" version of
        // illegal.equals(pkgName + "." + className)
        return pkgName != null
                && className.length() == illegal.length() - pkgNameLen - 1
                && illegal.charAt(pkgNameLen) == '.'
                && illegal.endsWith(className)
                && illegal.startsWith(pkgName);
    }

    /**
     * Is class of the same package.
     * @param className class name
     * @return true if same package class
     */
    private boolean isSamePackage(String className) {
        boolean isSamePackage = false;
        try {
            final ClassLoader classLoader = getClassLoader();
            if (classLoader != null) {
                final String fqName = pkgName + "." + className;
                classLoader.loadClass(fqName);
                // no ClassNotFoundException, fqName is a known class
                isSamePackage = true;
            }
        }
        catch (final ClassNotFoundException ignored) {
            // not a class from the same package
            isSamePackage = false;
        }
        return isSamePackage;
    }

    /**
     * Is Standard Class.
     * @param className class name
     * @param illegal illegal value
     * @return true if type is standard
     */
    private boolean isStandardClass(String className, String illegal) {
        boolean isStandardCalss = false;
        // class from java.lang
        if (illegal.length() - JAVA_LANG.length() == className.length()
            && illegal.endsWith(className)
            && illegal.startsWith(JAVA_LANG)) {
            // java.lang needs no import, but a class without import might
            // also come from the same file or be in the same package.
            // E.g. if a class defines an inner class "Boolean",
            // the expression "new Boolean()" refers to that class,
            // not to java.lang.Boolean

            final boolean isSameFile = classNames.contains(className);
            final boolean isSamePackage = isSamePackage(className);

            if (!isSameFile && !isSamePackage) {
                isStandardCalss = true;
            }
        }
        return isStandardCalss;
    }

    /**
     * Sets the classes that are illegal to instantiate.
     * @param names a comma separate list of class names
     */
    public void setClasses(String... names) {
        illegalClasses = Arrays.stream(names).collect(Collectors.toSet());
    }
}
