/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.scripting.core.dependencyScan;

import java.util.Collection;
import java.util.Set;

/**
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 *          <p/>
 *          Utils which store the shared code
 */
class ClassScanUtils {
    public static final String BINARY_PACKAGE = "\\/";

    private static final String DOMAIN_JAVA = "java.";
    private static final String DOMAIN_JAVAX = "javax.";
    private static final String DOMAIN_COM_SUN = "com.sun";
    private static final String DOMAIN_APACHE = "org.apache.";
    private static final String DOMAIN_MYFACES = "org.apache.myfaces";
    private static final String DOMAIN_JBOSS = "org.jboss";
    private static final String DOMAIN_SPRING = "org.springframework";
    private static final String DOMAIN_JUNIT = "org.junit";
    private static final String DOMAIN_ECLIPSE = "org.eclipse";
    private static final String DOMAIN_NETBEANS = "org.netbeans";
    private static final String DOMAIN_GROOVY = "groovy.";
    private static final String DOMAIN_SCALA = "scala.";
    private static final String DOMAIN_JYTHON = "jython.";
    private static final String DOMAIN_JRUBY = "jruby.";

    /**
     * checks if a given package or class
     * belongs to a standard namespaces which is
     * untouchable by an implementer
     *
     * @param in the page or fully qualified classname
     * @return true if it belongs to one of the standard namespaces, false if not
     */
    public static boolean isStandardNamespace(String in) {
        //We don't use a regexp here, because an test has shown that direct startsWith is 5 times as fast as applying
        //a precompiled regexp with match

        //shortcuts for a faster killing of the add before going into the heavier
        //whitelist check, this one kills off classes which belong to standard
        //and semi standard namespaces before whitelisting the rest
        return in.startsWith(DOMAIN_JAVA) ||
                in.startsWith(DOMAIN_JAVAX) ||
                in.startsWith(DOMAIN_COM_SUN) ||
                in.startsWith(DOMAIN_GROOVY) ||
                in.startsWith(DOMAIN_JYTHON) ||
                in.startsWith(DOMAIN_JRUBY) ||
                in.startsWith(DOMAIN_SCALA) ||
                in.startsWith(DOMAIN_JBOSS) ||
                in.startsWith(DOMAIN_SPRING) ||
                in.startsWith(DOMAIN_JUNIT) ||
                in.startsWith(DOMAIN_ECLIPSE) ||
                in.startsWith(DOMAIN_NETBEANS) ||

                //apache domain has to be treated specially myfaces can be referenced due to our tests and demos, otherwise this one
                //is also treated as taboo zone
                ((in.startsWith(DOMAIN_APACHE) &&
                        !in.startsWith(DOMAIN_MYFACES)));
    }

    /**
     * checks for an allowed namespaces from a given namespace list
     * if the class or package is in the list of allowed namespaces
     * a true is returned otherwise a false
     *
     * @param classOrPackage the class or package name to be checked for allowance
     * @param nameSpaces     the list of allowed namespaces
     * @return true if the namespace is within the boundaries of the whitelist false otherwise
     */
    @SuppressWarnings("unused")
    public static boolean allowedNamespaces(String classOrPackage, String[] nameSpaces) {

        //ok this is probably the fastest way to iterate hence we use this old construct
        //a direct or would be faster but we cannot do it here since we are not dynamic here
        int len = nameSpaces.length;
        for (int cnt = 0; cnt < len; cnt++) {
            if (classOrPackage.startsWith(nameSpaces[cnt])) {
                return true;
            }
        }
        return false;
    }

    /**
     * renames the internal member class descriptors of L<qualified classnamewith />; to its source name
     *
     * @param internalClassName the internal class name
     * @return the changed classname in its sourceform
     */
    public static String internalClassDescriptorToSource(String internalClassName) {
        //we strip the meta information which is not needed
        //aka start with ( strip all to )

        //()means usually beginning of a native type
        if (internalClassName.startsWith("(")) {
            internalClassName = internalClassName.substring(internalClassName.lastIndexOf(')') + 1);
        }

        //()I for single data types
        if (internalClassName.equals("") || internalClassName.length() == 1) {
            return null;
        }

        //fully qualified name with meta information
        if (internalClassName.endsWith(";")) {
            //we can skip all the other meta information, a class identifier on sub class level
            //has to start with L the format is <META ATTRIBUTES>L<CLASS QUALIFIED NAME>;
            //The meta attributes can be for instance [ for array
            internalClassName = internalClassName.substring(internalClassName.indexOf('L') + 1, internalClassName.length() - 1);
        }

        //normal fully qualified name with no meta info attached
        internalClassName = internalClassName.replaceAll(BINARY_PACKAGE, ".");
        return internalClassName;
    }

    /**
     * logs a dependency if it does not belong to the standard namespaces
     * and also it only is added if it belongs to our whitelist of
     * non standard namespaces (the standard check is just a short circuiting
     * for performance reasons, before going into the heavier whitelist
     * namespace check)
     *
     * @param dependencies the target which has to receive the dependency in source format
     * @param whiteList    the whitelist of allowed dependencies
     * @param parameters   the list of dependencies which have to be added
     */
    public static void logParmList(Collection<String> dependencies, final Set<String> whiteList, final String... parameters) {
        for (String singleParameter : parameters) {
            if (singleParameter == null) continue;
            if (singleParameter.equals("")) continue;
            singleParameter = internalClassDescriptorToSource(singleParameter);
            if (singleParameter == null || isStandardNamespace(singleParameter)) continue;

            String[] packages = singleParameter.split("\\.");

            StringBuilder fullPackage = null;
            for (String currPackage : packages) {
                if (fullPackage != null) {
                    fullPackage.append(".");
                    fullPackage.append(currPackage);
                } else {
                    fullPackage = new StringBuilder(singleParameter.length());
                    fullPackage.append(currPackage);
                }

                String tempPackage = fullPackage.toString();
                if (whiteList.contains(tempPackage)) {
                    dependencies.add(singleParameter);
                    break;
                }
            }
        }
    }
}
