/*
 * 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 jakarta.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 <T> T eval(String expression) {
        @SuppressWarnings("unchecked")
        T result = (T) getValue(expression, Object.class);
        return result;
    }


    public <T> T getValue(String expression, Class<T> 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, Thread.currentThread().getContextClassLoader());
        }

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

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

        if (function.isEmpty()) {
            function = sig.getName();
        }

        // Only returns public methods. Module access is checked below.
        Method[] methods = clazz.getMethods();

        for (Method method : methods) {
            if (!Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            if (!Util.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();
                    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 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
        if (!Modifier.isStatic(modifiers) || !Util.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;

        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.isEmpty()) {
                    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";
                                case "byte" -> parameterTypeName = "B";
                                case "char" -> parameterTypeName = "C";
                                case "double" -> parameterTypeName = "D";
                                case "float" -> parameterTypeName = "F";
                                case "int" -> parameterTypeName = "I";
                                case "long" -> parameterTypeName = "J";
                                case "short" -> parameterTypeName = "S";
                                default -> {
                                    // Should never happen
                                }
                            }
                        } 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();
                            sb.append("[".repeat(dimension));
                            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;
        }
    }
}
