/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard;

import proguard.classfile.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;

import java.util.List;

/**
 * This class checks if the user has forgotten to fully qualify any classes
 * in the configuration.
 *
 * @author Eric Lafortune
 */
public class FullyQualifiedClassNameChecker
extends      SimplifiedVisitor
implements   ClassVisitor
{
    private static final String INVALID_CLASS_EXTENSION = ClassUtil.internalClassName(ClassConstants.CLASS_FILE_EXTENSION);


    private final ClassPool      programClassPool;
    private final ClassPool      libraryClassPool;
    private final WarningPrinter notePrinter;


    /**
     * Creates a new FullyQualifiedClassNameChecker.
     */
    public FullyQualifiedClassNameChecker(ClassPool      programClassPool,
                                          ClassPool      libraryClassPool,
                                          WarningPrinter notePrinter)
    {
        this.programClassPool = programClassPool;
        this.libraryClassPool = libraryClassPool;
        this.notePrinter      = notePrinter;
    }


    /**
     * Checks the classes mentioned in the given class specifications, printing
     * notes if necessary.
     */
    public void checkClassSpecifications(List classSpecifications)
    {
        if (classSpecifications != null)
        {
            for (int index = 0; index < classSpecifications.size(); index++)
            {
                ClassSpecification classSpecification =
                    (ClassSpecification)classSpecifications.get(index);

                checkType(classSpecification.annotationType);
                checkClassName(classSpecification.className);
                checkType(classSpecification.extendsAnnotationType);
                checkClassName(classSpecification.extendsClassName);

                checkMemberSpecifications(classSpecification.fieldSpecifications,  true);
                checkMemberSpecifications(classSpecification.methodSpecifications, false);
            }
        }
    }


    /**
     * Checks the classes mentioned in the given class member specifications,
     * printing notes if necessary.
     */
    private void checkMemberSpecifications(List memberSpecifications, boolean isField)
    {
        if (memberSpecifications != null)
        {
            for (int index = 0; index < memberSpecifications.size(); index++)
            {
                MemberSpecification memberSpecification =
                    (MemberSpecification)memberSpecifications.get(index);

                checkType(memberSpecification.annotationType);

                if (isField)
                {
                     checkType(memberSpecification.descriptor);
                }
                else
                {
                    checkDescriptor(memberSpecification.descriptor);
                }
            }
        }
    }


    /**
     * Checks the classes mentioned in the given class member descriptor,
     * printing notes if necessary.
     */
    private void checkDescriptor(String descriptor)
    {
        if (descriptor != null)
        {
            InternalTypeEnumeration internalTypeEnumeration =
                new InternalTypeEnumeration(descriptor);

            checkType(internalTypeEnumeration.returnType());

            while (internalTypeEnumeration.hasMoreTypes())
            {
                checkType(internalTypeEnumeration.nextType());
            }
        }
    }


    /**
     * Checks the class mentioned in the given type (if any),
     * printing notes if necessary.
     */
    private void checkType(String type)
    {
        if (type != null)
        {
            checkClassName(ClassUtil.internalClassNameFromType(type));
        }
    }


    /**
     * Checks the specified class (if any),
     * printing notes if necessary.
     */
    private void checkClassName(String className)
    {
        if (className != null                            &&
            !containsWildCards(className)                &&
            programClassPool.getClass(className) == null &&
            libraryClassPool.getClass(className) == null &&
            notePrinter.accepts(className))
        {
            notePrinter.print(className,
                              "Note: the configuration refers to the unknown class '" +
                              ClassUtil.externalClassName(className) + "'");

            // Strip "/class" or replace the package name by a wildcard.
            int lastSeparatorIndex =
                className.lastIndexOf(ClassConstants.PACKAGE_SEPARATOR);

            String fullyQualifiedClassName =
                className.endsWith(INVALID_CLASS_EXTENSION) ?
                    className.substring(0, lastSeparatorIndex) :
                    "**" + ClassConstants.PACKAGE_SEPARATOR + className.substring(lastSeparatorIndex + 1);

            // Suggest matching classes.
            ClassNameFilter classNameFilter =
                new ClassNameFilter(fullyQualifiedClassName, this);

            programClassPool.classesAccept(classNameFilter);
            libraryClassPool.classesAccept(classNameFilter);
        }
    }


    private static boolean containsWildCards(String string)
    {
        return string != null &&
            (string.indexOf('!')   >= 0 ||
             string.indexOf('*')   >= 0 ||
             string.indexOf('?')   >= 0 ||
             string.indexOf(',')   >= 0 ||
             string.indexOf("///") >= 0);
    }


    // Implementations for ClassVisitor.

    public void visitAnyClass(Clazz clazz)
    {
        System.out.println("      Maybe you meant the fully qualified name '" +
                           ClassUtil.externalClassName(clazz.getName()) + "'?");
    }
}
