/*
 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.tools.classfile;

import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import com.sun.tools.classfile.Dependency.Filter;
import com.sun.tools.classfile.Dependency.Finder;
import com.sun.tools.classfile.Dependency.Location;
import com.sun.tools.classfile.Type.ArrayType;
import com.sun.tools.classfile.Type.ClassSigType;
import com.sun.tools.classfile.Type.ClassType;
import com.sun.tools.classfile.Type.MethodType;
import com.sun.tools.classfile.Type.SimpleType;
import com.sun.tools.classfile.Type.TypeParamType;
import com.sun.tools.classfile.Type.WildcardType;
import static com.sun.tools.classfile.ConstantPool.*;

/**
 * A framework for determining {@link Dependency dependencies} between class files.
 *
 * A {@link Dependency.Finder finder} is used to identify the dependencies of
 * individual classes. Some finders may return subtypes of {@code Dependency} to
 * further characterize the type of dependency, such as a dependency on a
 * method within a class.
 *
 * A {@link Dependency.Filter filter} may be used to restrict the set of
 * dependencies found by a finder.
 *
 * Dependencies that are found may be passed to a {@link Dependencies.Recorder
 * recorder} so that the dependencies can be stored in a custom data structure.
 */
public class Dependencies {
    /**
     * Thrown when a class file cannot be found.
     */
    public static class ClassFileNotFoundException extends Exception {
        private static final long serialVersionUID = 3632265927794475048L;

        public ClassFileNotFoundException(String className) {
            super(className);
            this.className = className;
        }

        public ClassFileNotFoundException(String className, Throwable cause) {
            this(className);
            initCause(cause);
        }

        public final String className;
    }

    /**
     * Thrown when an exception is found processing a class file.
     */
    public static class ClassFileError extends Error {
        private static final long serialVersionUID = 4111110813961313203L;

        public ClassFileError(Throwable cause) {
            initCause(cause);
        }
    }

    /**
     * Service provider interface to locate and read class files.
     */
    public interface ClassFileReader {
        /**
         * Get the ClassFile object for a specified class.
         * @param className the name of the class to be returned.
         * @return the ClassFile for the given class
         * @throws Dependencies.ClassFileNotFoundException if the classfile cannot be
         *   found
         */
        public ClassFile getClassFile(String className)
                throws ClassFileNotFoundException;
    }

    /**
     * Service provide interface to handle results.
     */
    public interface Recorder {
        /**
         * Record a dependency that has been found.
         * @param d
         */
        public void addDependency(Dependency d);
    }

    /**
     * Get the  default finder used to locate the dependencies for a class.
     * @return the default finder
     */
    public static Finder getDefaultFinder() {
        return new APIDependencyFinder(AccessFlags.ACC_PRIVATE);
    }

    /**
     * Get a finder used to locate the API dependencies for a class.
     * These include the superclass, superinterfaces, and classes referenced in
     * the declarations of fields and methods.  The fields and methods that
     * are checked can be limited according to a specified access.
     * The access parameter must be one of {@link AccessFlags#ACC_PUBLIC ACC_PUBLIC},
     * {@link AccessFlags#ACC_PRIVATE ACC_PRIVATE},
     * {@link AccessFlags#ACC_PROTECTED ACC_PROTECTED}, or 0 for
     * package private access. Members with greater than or equal accessibility
     * to that specified will be searched for dependencies.
     * @param access the access of members to be checked
     * @return an API finder
     */
    public static Finder getAPIFinder(int access) {
        return new APIDependencyFinder(access);
    }

    /**
     * Get a finder to do class dependency analysis.
     *
     * @return a Class dependency finder
     */
    public static Finder getClassDependencyFinder() {
        return new ClassDependencyFinder();
    }

    /**
     * Get the finder used to locate the dependencies for a class.
     * @return the finder
     */
    public Finder getFinder() {
        if (finder == null)
            finder = getDefaultFinder();
        return finder;
    }

    /**
     * Set the finder used to locate the dependencies for a class.
     * @param f the finder
     */
    public void setFinder(Finder f) {
        f.getClass(); // null check
        finder = f;
    }

    /**
     * Get the default filter used to determine included when searching
     * the transitive closure of all the dependencies.
     * Unless overridden, the default filter accepts all dependencies.
     * @return the default filter.
     */
    public static Filter getDefaultFilter() {
        return DefaultFilter.instance();
    }

    /**
     * Get a filter which uses a regular expression on the target's class name
     * to determine if a dependency is of interest.
     * @param pattern the pattern used to match the target's class name
     * @return a filter for matching the target class name with a regular expression
     */
    public static Filter getRegexFilter(Pattern pattern) {
        return new TargetRegexFilter(pattern);
    }

    /**
     * Get a filter which checks the package of a target's class name
     * to determine if a dependency is of interest. The filter checks if the
     * package of the target's class matches any of a set of given package
     * names. The match may optionally match subpackages of the given names as well.
     * @param packageNames the package names used to match the target's class name
     * @param matchSubpackages whether or not to match subpackages as well
     * @return a filter for checking the target package name against a list of package names
     */
    public static Filter getPackageFilter(Set<String> packageNames, boolean matchSubpackages) {
        return new TargetPackageFilter(packageNames, matchSubpackages);
    }

    /**
     * Get the filter used to determine the dependencies included when searching
     * the transitive closure of all the dependencies.
     * Unless overridden, the default filter accepts all dependencies.
     * @return the filter
     */
    public Filter getFilter() {
        if (filter == null)
            filter = getDefaultFilter();
        return filter;
    }

    /**
     * Set the filter used to determine the dependencies included when searching
     * the transitive closure of all the dependencies.
     * @param f the filter
     */
    public void setFilter(Filter f) {
        f.getClass(); // null check
        filter = f;
    }

    /**
     * Find the dependencies of a class, using the current
     * {@link Dependencies#getFinder finder} and
     * {@link Dependencies#getFilter filter}.
     * The search may optionally include the transitive closure of all the
     * filtered dependencies, by also searching in the classes named in those
     * dependencies.
     * @param classFinder a finder to locate class files
     * @param rootClassNames the names of the root classes from which to begin
     *      searching
     * @param transitiveClosure whether or not to also search those classes
     *      named in any filtered dependencies that are found.
     * @return the set of dependencies that were found
     * @throws ClassFileNotFoundException if a required class file cannot be found
     * @throws ClassFileError if an error occurs while processing a class file,
     *      such as an error in the internal class file structure.
     */
    public Set<Dependency> findAllDependencies(
            ClassFileReader classFinder, Set<String> rootClassNames,
            boolean transitiveClosure)
            throws ClassFileNotFoundException {
        final Set<Dependency> results = new HashSet<>();
        Recorder r = new Recorder() {
            public void addDependency(Dependency d) {
                results.add(d);
            }
        };
        findAllDependencies(classFinder, rootClassNames, transitiveClosure, r);
        return results;
    }

    /**
     * Find the dependencies of a class, using the current
     * {@link Dependencies#getFinder finder} and
     * {@link Dependencies#getFilter filter}.
     * The search may optionally include the transitive closure of all the
     * filtered dependencies, by also searching in the classes named in those
     * dependencies.
     * @param classFinder a finder to locate class files
     * @param rootClassNames the names of the root classes from which to begin
     *      searching
     * @param transitiveClosure whether or not to also search those classes
     *      named in any filtered dependencies that are found.
     * @param recorder a recorder for handling the results
     * @throws ClassFileNotFoundException if a required class file cannot be found
     * @throws ClassFileError if an error occurs while processing a class file,
     *      such as an error in the internal class file structure.
     */
    public void findAllDependencies(
            ClassFileReader classFinder, Set<String> rootClassNames,
            boolean transitiveClosure, Recorder recorder)
            throws ClassFileNotFoundException {
        Set<String> doneClasses = new HashSet<>();

        getFinder();  // ensure initialized
        getFilter();  // ensure initialized

        // Work queue of names of classfiles to be searched.
        // Entries will be unique, and for classes that do not yet have
        // dependencies in the results map.
        Deque<String> deque = new LinkedList<>(rootClassNames);

        String className;
        while ((className = deque.poll()) != null) {
            assert (!doneClasses.contains(className));
            doneClasses.add(className);

            ClassFile cf = classFinder.getClassFile(className);

            // The following code just applies the filter to the dependencies
            // followed for the transitive closure.
            for (Dependency d: finder.findDependencies(cf)) {
                recorder.addDependency(d);
                if (transitiveClosure && filter.accepts(d)) {
                    String cn = d.getTarget().getClassName();
                    if (!doneClasses.contains(cn))
                        deque.add(cn);
                }
            }
        }
    }

    private Filter filter;
    private Finder finder;

    /**
     * A location identifying a class.
     */
    static class SimpleLocation implements Location {
        public SimpleLocation(String name) {
            this.name = name;
            this.className = name.replace('/', '.');
        }

        public String getName() {
            return name;
        }

        public String getClassName() {
            return className;
        }

        public String getPackageName() {
            int i = name.lastIndexOf('/');
            return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
        }

        @Override
        public boolean equals(Object other) {
            if (this == other)
                return true;
            if (!(other instanceof SimpleLocation))
                return false;
            return (name.equals(((SimpleLocation) other).name));
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }

        @Override
        public String toString() {
            return name;
        }

        private String name;
        private String className;
    }

    /**
     * A dependency of one class on another.
     */
    static class SimpleDependency implements Dependency {
        public SimpleDependency(Location origin, Location target) {
            this.origin = origin;
            this.target = target;
        }

        public Location getOrigin() {
            return origin;
        }

        public Location getTarget() {
            return target;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other)
                return true;
            if (!(other instanceof SimpleDependency))
                return false;
            SimpleDependency o = (SimpleDependency) other;
            return (origin.equals(o.origin) && target.equals(o.target));
        }

        @Override
        public int hashCode() {
            return origin.hashCode() * 31 + target.hashCode();
        }

        @Override
        public String toString() {
            return origin + ":" + target;
        }

        private Location origin;
        private Location target;
    }


    /**
     * This class accepts all dependencies.
     */
    static class DefaultFilter implements Filter {
        private static DefaultFilter instance;

        static DefaultFilter instance() {
            if (instance == null)
                instance = new DefaultFilter();
            return instance;
        }

        public boolean accepts(Dependency dependency) {
            return true;
        }
    }

    /**
     * This class accepts those dependencies whose target's class name matches a
     * regular expression.
     */
    static class TargetRegexFilter implements Filter {
        TargetRegexFilter(Pattern pattern) {
            this.pattern = pattern;
        }

        public boolean accepts(Dependency dependency) {
            return pattern.matcher(dependency.getTarget().getClassName()).matches();
        }

        private final Pattern pattern;
    }

    /**
     * This class accepts those dependencies whose class name is in a given
     * package.
     */
    static class TargetPackageFilter implements Filter {
        TargetPackageFilter(Set<String> packageNames, boolean matchSubpackages) {
            for (String pn: packageNames) {
                if (pn.length() == 0) // implies null check as well
                    throw new IllegalArgumentException();
            }
            this.packageNames = packageNames;
            this.matchSubpackages = matchSubpackages;
        }

        public boolean accepts(Dependency dependency) {
            String pn = dependency.getTarget().getPackageName();
            if (packageNames.contains(pn))
                return true;

            if (matchSubpackages) {
                for (String n: packageNames) {
                    if (pn.startsWith(n + "."))
                        return true;
                }
            }

            return false;
        }

        private final Set<String> packageNames;
        private final boolean matchSubpackages;
    }

    /**
     * This class identifies class names directly or indirectly in the constant pool.
     */
    static class ClassDependencyFinder extends BasicDependencyFinder {
        public Iterable<? extends Dependency> findDependencies(ClassFile classfile) {
            Visitor v = new Visitor(classfile);
            for (CPInfo cpInfo: classfile.constant_pool.entries()) {
                v.scan(cpInfo);
            }
            try {
                v.addClass(classfile.super_class);
                v.addClasses(classfile.interfaces);
                v.scan(classfile.attributes);

                for (Field f : classfile.fields) {
                    v.scan(f.descriptor, f.attributes);
                }
                for (Method m : classfile.methods) {
                    v.scan(m.descriptor, m.attributes);
                    Exceptions_attribute e =
                        (Exceptions_attribute)m.attributes.get(Attribute.Exceptions);
                    if (e != null) {
                        v.addClasses(e.exception_index_table);
                    }
                }
            } catch (ConstantPoolException e) {
                throw new ClassFileError(e);
            }

            return v.deps;
        }
    }

    /**
     * This class identifies class names in the signatures of classes, fields,
     * and methods in a class.
     */
    static class APIDependencyFinder extends BasicDependencyFinder {
        APIDependencyFinder(int access) {
            switch (access) {
                case AccessFlags.ACC_PUBLIC:
                case AccessFlags.ACC_PROTECTED:
                case AccessFlags.ACC_PRIVATE:
                case 0:
                    showAccess = access;
                    break;
                default:
                    throw new IllegalArgumentException("invalid access 0x"
                            + Integer.toHexString(access));
            }
        }

        public Iterable<? extends Dependency> findDependencies(ClassFile classfile) {
            try {
                Visitor v = new Visitor(classfile);
                v.addClass(classfile.super_class);
                v.addClasses(classfile.interfaces);
                // inner classes?
                for (Field f : classfile.fields) {
                    if (checkAccess(f.access_flags))
                        v.scan(f.descriptor, f.attributes);
                }
                for (Method m : classfile.methods) {
                    if (checkAccess(m.access_flags)) {
                        v.scan(m.descriptor, m.attributes);
                        Exceptions_attribute e =
                                (Exceptions_attribute) m.attributes.get(Attribute.Exceptions);
                        if (e != null)
                            v.addClasses(e.exception_index_table);
                    }
                }
                return v.deps;
            } catch (ConstantPoolException e) {
                throw new ClassFileError(e);
            }
        }

        boolean checkAccess(AccessFlags flags) {
            // code copied from javap.Options.checkAccess
            boolean isPublic = flags.is(AccessFlags.ACC_PUBLIC);
            boolean isProtected = flags.is(AccessFlags.ACC_PROTECTED);
            boolean isPrivate = flags.is(AccessFlags.ACC_PRIVATE);
            boolean isPackage = !(isPublic || isProtected || isPrivate);

            if ((showAccess == AccessFlags.ACC_PUBLIC) && (isProtected || isPrivate || isPackage))
                return false;
            else if ((showAccess == AccessFlags.ACC_PROTECTED) && (isPrivate || isPackage))
                return false;
            else if ((showAccess == 0) && (isPrivate))
                return false;
            else
                return true;
        }

        private int showAccess;
    }

    static abstract class BasicDependencyFinder implements Finder {
        private Map<String,Location> locations = new HashMap<>();

        Location getLocation(String className) {
            Location l = locations.get(className);
            if (l == null)
                locations.put(className, l = new SimpleLocation(className));
            return l;
        }

        class Visitor implements ConstantPool.Visitor<Void,Void>, Type.Visitor<Void, Void> {
            private ConstantPool constant_pool;
            private Location origin;
            Set<Dependency> deps;

            Visitor(ClassFile classFile) {
                try {
                    constant_pool = classFile.constant_pool;
                    origin = getLocation(classFile.getName());
                    deps = new HashSet<>();
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            void scan(Descriptor d, Attributes attrs) {
                try {
                    scan(new Signature(d.index).getType(constant_pool));
                    scan(attrs);
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            void scan(CPInfo cpInfo) {
                cpInfo.accept(this, null);
            }

            void scan(Type t) {
                t.accept(this, null);
            }

            void scan(Attributes attrs) {
                try {
                    Signature_attribute sa = (Signature_attribute)attrs.get(Attribute.Signature);
                    if (sa != null)
                        scan(sa.getParsedSignature().getType(constant_pool));

                    scan((RuntimeVisibleAnnotations_attribute)
                            attrs.get(Attribute.RuntimeVisibleAnnotations));
                    scan((RuntimeVisibleParameterAnnotations_attribute)
                            attrs.get(Attribute.RuntimeVisibleParameterAnnotations));
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            private void scan(RuntimeAnnotations_attribute attr) throws ConstantPoolException {
                if (attr == null) {
                    return;
                }
                for (int i = 0; i < attr.annotations.length; i++) {
                    int index = attr.annotations[i].type_index;
                    scan(new Signature(index).getType(constant_pool));
                }
            }

            private void scan(RuntimeParameterAnnotations_attribute attr) throws ConstantPoolException {
                if (attr == null) {
                    return;
                }
                for (int param = 0; param < attr.parameter_annotations.length; param++) {
                    for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
                        int index = attr.parameter_annotations[param][i].type_index;
                        scan(new Signature(index).getType(constant_pool));
                    }
                }
            }

            void addClass(int index) throws ConstantPoolException {
                if (index != 0) {
                    String name = constant_pool.getClassInfo(index).getBaseName();
                    if (name != null)
                        addDependency(name);
                }
            }

            void addClasses(int[] indices) throws ConstantPoolException {
                for (int i: indices)
                    addClass(i);
            }

            private void addDependency(String name) {
                deps.add(new SimpleDependency(origin, getLocation(name)));
            }

            // ConstantPool.Visitor methods

            public Void visitClass(CONSTANT_Class_info info, Void p) {
                try {
                    if (info.getName().startsWith("["))
                        new Signature(info.name_index).getType(constant_pool).accept(this, null);
                    else
                        addDependency(info.getBaseName());
                    return null;
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            public Void visitDouble(CONSTANT_Double_info info, Void p) {
                return null;
            }

            public Void visitFieldref(CONSTANT_Fieldref_info info, Void p) {
                return visitRef(info, p);
            }

            public Void visitFloat(CONSTANT_Float_info info, Void p) {
                return null;
            }

            public Void visitInteger(CONSTANT_Integer_info info, Void p) {
                return null;
            }

            public Void visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
                return visitRef(info, p);
            }

            public Void visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
                return null;
            }

            public Void visitLong(CONSTANT_Long_info info, Void p) {
                return null;
            }

            public Void visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
                return null;
            }

            public Void visitMethodType(CONSTANT_MethodType_info info, Void p) {
                return null;
            }

            public Void visitMethodref(CONSTANT_Methodref_info info, Void p) {
                return visitRef(info, p);
            }

            public Void visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
                try {
                    new Signature(info.type_index).getType(constant_pool).accept(this, null);
                    return null;
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            public Void visitString(CONSTANT_String_info info, Void p) {
                return null;
            }

            public Void visitUtf8(CONSTANT_Utf8_info info, Void p) {
                return null;
            }

            private Void visitRef(CPRefInfo info, Void p) {
                try {
                    visitClass(info.getClassInfo(), p);
                    return null;
                } catch (ConstantPoolException e) {
                    throw new ClassFileError(e);
                }
            }

            // Type.Visitor methods

            private void findDependencies(Type t) {
                if (t != null)
                    t.accept(this, null);
            }

            private void findDependencies(List<? extends Type> ts) {
                if (ts != null) {
                    for (Type t: ts)
                        t.accept(this, null);
                }
            }

            public Void visitSimpleType(SimpleType type, Void p) {
                return null;
            }

            public Void visitArrayType(ArrayType type, Void p) {
                findDependencies(type.elemType);
                return null;
            }

            public Void visitMethodType(MethodType type, Void p) {
                findDependencies(type.paramTypes);
                findDependencies(type.returnType);
                findDependencies(type.throwsTypes);
                findDependencies(type.typeParamTypes);
                return null;
            }

            public Void visitClassSigType(ClassSigType type, Void p) {
                findDependencies(type.superclassType);
                findDependencies(type.superinterfaceTypes);
                return null;
            }

            public Void visitClassType(ClassType type, Void p) {
                findDependencies(type.outerType);
                addDependency(type.getBinaryName());
                findDependencies(type.typeArgs);
                return null;
            }

            public Void visitTypeParamType(TypeParamType type, Void p) {
                findDependencies(type.classBound);
                findDependencies(type.interfaceBounds);
                return null;
            }

            public Void visitWildcardType(WildcardType type, Void p) {
                findDependencies(type.boundType);
                return null;
            }
        }
    }
}
