/*
 * 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 javax.el;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;

/**
 * @since EL 3.0
 */
public class ELProcessor {

    private static final Set<String> PRIMITIVES = new HashSet<>();
    static {
        PRIMITIVES.add("boolean");
        PRIMITIVES.add("byte");
        PRIMITIVES.add("char");
        PRIMITIVES.add("double");
        PRIMITIVES.add("float");
        PRIMITIVES.add("int");
        PRIMITIVES.add("long");
        PRIMITIVES.add("short");
    }

    private static final String[] EMPTY_STRING_ARRAY = new String[0];

    private final ELManager manager = new ELManager();
    private final ELContext context = manager.getELContext();
    private final ExpressionFactory factory = ELManager.getExpressionFactory();


    public ELManager getELManager() {
        return manager;
    }


    public Object eval(String expression) {
        return getValue(expression, Object.class);
    }


    public Object getValue(String expression, Class<?> expectedType) {
        ValueExpression ve = factory.createValueExpression(
                context, bracket(expression), expectedType);
        return ve.getValue(context);
    }


    public void setValue(String expression, Object value) {
        ValueExpression ve = factory.createValueExpression(
                context, bracket(expression), Object.class);
        ve.setValue(context, value);
    }


    public void setVariable(String variable, String expression) {
        if (expression == null) {
            manager.setVariable(variable, null);
        } else {
            ValueExpression ve = factory.createValueExpression(
                    context, bracket(expression), Object.class);
            manager.setVariable(variable, ve);
        }
    }


    public void defineFunction(String prefix, String function, String className,
            String methodName) throws ClassNotFoundException,
            NoSuchMethodException {

        if (prefix == null || function == null || className == null ||
                methodName == null) {
            throw new NullPointerException(Util.message(
                    context, "elProcessor.defineFunctionNullParams"));
        }

        // Check the imports
        Class<?> clazz = context.getImportHandler().resolveClass(className);

        if (clazz == null) {
            clazz = Class.forName(className, true, Util.getContextClassLoader());
        }

        if (!Modifier.isPublic(clazz.getModifiers())) {
            throw new ClassNotFoundException(Util.message(context,
                    "elProcessor.defineFunctionInvalidClass", className));
        }

        MethodSignature sig =
                new MethodSignature(context, methodName, className);

        if (function.length() == 0) {
            function = sig.getName();
        }

        // Only returns public methods. Java 9+ access is checked below.
        Method methods[] = clazz.getMethods();
        JreCompat jreCompat = JreCompat.getInstance();

        for (Method method : methods) {
            if (!Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            if (!jreCompat.canAccess(null, method)) {
                continue;
            }
            if (method.getName().equals(sig.getName())) {
                if (sig.getParamTypeNames() == null) {
                    // Only a name provided, no signature so map the first
                    // method declared
                    manager.mapFunction(prefix, function, method);
                    return;
                }
                if (sig.getParamTypeNames().length != method.getParameterTypes().length) {
                    continue;
                }
                if (sig.getParamTypeNames().length == 0) {
                    manager.mapFunction(prefix, function, method);
                    return;
                } else {
                    Class<?>[] types = method.getParameterTypes();
                    String[] typeNames = sig.getParamTypeNames();
                    if (types.length == typeNames.length) {
                        boolean match = true;
                        for (int i = 0; i < types.length; i++) {
                            if (i == types.length -1 && method.isVarArgs()) {
                                String typeName = typeNames[i];
                                if (typeName.endsWith("...")) {
                                    typeName = typeName.substring(0, typeName.length() - 3);
                                    if (!typeName.equals(types[i].getName())) {
                                        match = false;
                                    }
                                } else {
                                    match = false;
                                }
                            } else if (!types[i].getName().equals(typeNames[i])) {
                                match = false;
                                break;
                            }
                        }
                        if (match) {
                            manager.mapFunction(prefix, function, method);
                            return;
                        }
                    }
                }
            }
        }

        throw new NoSuchMethodException(Util.message(context,
                "elProcessor.defineFunctionNoMethod", methodName, className));
    }


    /**
     * Map a method to a function name.
     *
     * @param prefix    Function prefix
     * @param function  Function name
     * @param method    Method
     *
     * @throws NullPointerException
     *              If any of the arguments are null
     * @throws NoSuchMethodException
     *              If the method is not static
     */
    public void defineFunction(String prefix, String function, Method method)
            throws java.lang.NoSuchMethodException {

        if (prefix == null || function == null || method == null) {
            throw new NullPointerException(Util.message(
                    context, "elProcessor.defineFunctionNullParams"));
        }

        int modifiers = method.getModifiers();

        // Check for static, public method and module access for Java 9+
        JreCompat jreCompat = JreCompat.getInstance();
        if (!Modifier.isStatic(modifiers) || !jreCompat.canAccess(null, method)) {
            throw new NoSuchMethodException(Util.message(context,
                    "elProcessor.defineFunctionInvalidMethod", method.getName(),
                    method.getDeclaringClass().getName()));
        }

        manager.mapFunction(prefix, function, method);
    }


    public void defineBean(String name, Object bean) {
        manager.defineBean(name, bean);
    }


    private static String bracket(String expression) {
        return "${" + expression + "}";
    }

    private static class MethodSignature {

        private final String name;
        private final String[] parameterTypeNames;

        public MethodSignature(ELContext context, String methodName,
                String className) throws NoSuchMethodException {

            int paramIndex = methodName.indexOf('(');

            if (paramIndex == -1) {
                name = methodName.trim();
                parameterTypeNames = null;
            } else {
                String returnTypeAndName = methodName.substring(0, paramIndex).trim();
                // Assume that the return type and the name are separated by
                // whitespace. Given the use of trim() above, there should only
                // be one sequence of whitespace characters.
                int wsPos = -1;
                for (int i = 0; i < returnTypeAndName.length(); i++) {
                    if (Character.isWhitespace(returnTypeAndName.charAt(i))) {
                        wsPos = i;
                        break;
                    }
                }
                if (wsPos == -1) {
                    throw new NoSuchMethodException();
                }
                name = returnTypeAndName.substring(wsPos).trim();

                String paramString = methodName.substring(paramIndex).trim();
                // We know the params start with '(', check they end with ')'
                if (!paramString.endsWith(")")) {
                    throw new NoSuchMethodException(Util.message(context,
                            "elProcessor.defineFunctionInvalidParameterList",
                            paramString, methodName, className));
                }
                // Trim '(' and ')'
                paramString = paramString.substring(1, paramString.length() - 1).trim();
                if (paramString.length() == 0) {
                    parameterTypeNames = EMPTY_STRING_ARRAY;
                } else {
                    parameterTypeNames = paramString.split(",");
                    ImportHandler importHandler = context.getImportHandler();
                    for (int i = 0; i < parameterTypeNames.length; i++) {
                        String parameterTypeName = parameterTypeNames[i].trim();
                        int dimension = 0;
                        int bracketPos = parameterTypeName.indexOf('[');
                        if (bracketPos > -1) {
                            String parameterTypeNameOnly =
                                    parameterTypeName.substring(0, bracketPos).trim();
                            while (bracketPos > -1) {
                                dimension++;
                                bracketPos = parameterTypeName.indexOf('[', bracketPos+ 1);
                            }
                            parameterTypeName = parameterTypeNameOnly;
                        }
                        boolean varArgs = false;
                        if (parameterTypeName.endsWith("...")) {
                            varArgs = true;
                            dimension = 1;
                            parameterTypeName = parameterTypeName.substring(
                                    0, parameterTypeName.length() -3).trim();
                        }
                        boolean isPrimitive = PRIMITIVES.contains(parameterTypeName);
                        if (isPrimitive && dimension > 0) {
                            // When in an array, class name changes for primitive
                            switch(parameterTypeName)
                            {
                                case "boolean":
                                    parameterTypeName = "Z";
                                    break;
                                case "byte":
                                    parameterTypeName = "B";
                                    break;
                                case "char":
                                    parameterTypeName = "C";
                                    break;
                                case "double":
                                    parameterTypeName = "D";
                                    break;
                                case "float":
                                    parameterTypeName = "F";
                                    break;
                                case "int":
                                    parameterTypeName = "I";
                                    break;
                                case "long":
                                    parameterTypeName = "J";
                                    break;
                                case "short":
                                    parameterTypeName = "S";
                                    break;
                                default:
                                    // Should never happen
                                    break;
                            }
                        } else  if (!isPrimitive &&
                                !parameterTypeName.contains(".")) {
                            Class<?> clazz = importHandler.resolveClass(
                                    parameterTypeName);
                            if (clazz == null) {
                                throw new NoSuchMethodException(Util.message(
                                        context,
                                        "elProcessor.defineFunctionInvalidParameterTypeName",
                                        parameterTypeNames[i], methodName,
                                        className));
                            }
                            parameterTypeName = clazz.getName();
                        }
                        if (dimension > 0) {
                            // Convert to array form of class name
                            StringBuilder sb = new StringBuilder();
                            for (int j = 0; j < dimension; j++) {
                                sb.append('[');
                            }
                            if (!isPrimitive) {
                                sb.append('L');
                            }
                            sb.append(parameterTypeName);
                            if (!isPrimitive) {
                                sb.append(';');
                            }
                            parameterTypeName = sb.toString();
                        }
                        if (varArgs) {
                            parameterTypeName += "...";
                        }
                        parameterTypeNames[i] = parameterTypeName;
                    }
                }
            }

        }

        public String getName() {
            return name;
        }

        /**
         * @return <code>null</code> if just the method name was specified, an
         *         empty List if an empty parameter list was specified - i.e. ()
         *         - otherwise an ordered list of parameter type names
         */
        public String[] getParamTypeNames() {
            return parameterTypeNames;
        }
    }
}
