/*
 * 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 freemarker.ext.jsp;

import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import freemarker.template.utility.ClassUtil;
import freemarker.template.utility.StringUtil;

final class TaglibMethodUtil {

    private TaglibMethodUtil() {
        // Not meant to be instantiated
    }

    private static final Pattern FUNCTION_SIGNATURE_PATTERN = 
            Pattern.compile("^([\\w\\.]+(\\s*\\[\\s*\\])?)\\s+([\\w]+)\\s*\\((.*)\\)$");
    private static final Pattern FUNCTION_PARAMETER_PATTERN = 
            Pattern.compile("^([\\w\\.]+)(\\s*\\[\\s*\\])?$");

    /**
     * Finds method by function signature string which is compliant with
     * Tag Library function signature in Java Server Page (TM) Specification.
     * A function signature example is as follows: {@code java.lang.String nickName( java.lang.String, int)}
     * 
     * @param clazz Class having the method.
     * @param signature Java Server Page (TM) Specification compliant function signature string.
     * @return method if found.
     */
    public static Method getMethodByFunctionSignature(Class clazz, String signature)
            throws SecurityException, NoSuchMethodException, ClassNotFoundException {
        Matcher m1 = FUNCTION_SIGNATURE_PATTERN.matcher(signature);

        if (!m1.matches()) {
            throw new IllegalArgumentException("Invalid function signature.");
        }

            String methodName = m1.group(3);
            String params = m1.group(4).trim();
            Class [] paramTypes = null;

            if ("".equals(params)) {
                paramTypes = new Class[0];
            } else {
                String [] paramsArray = StringUtil.split(params, ',');
                paramTypes = new Class[paramsArray.length];
                String token = null;
                String paramType = null;
                boolean isPrimitive = false;
                boolean isArrayType = false;
                Matcher m2 = null;

                for (int i = 0; i < paramsArray.length; i++) {
                    token = paramsArray[i].trim();
                    m2 = FUNCTION_PARAMETER_PATTERN.matcher(token);

                    if (!m2.matches()) {
                        throw new IllegalArgumentException("Invalid argument signature: '" + token + "'.");
                    }

                    paramType = m2.group(1);
                    isPrimitive = (paramType.indexOf('.') == -1);
                    isArrayType = (m2.group(2) != null);

                    if (isPrimitive) {
                        if ("byte".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? byte[].class : byte.class);
                        } else if ("short".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? short[].class : short.class);
                        } else if ("int".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? int[].class : int.class);
                        } else if ("long".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? long[].class : long.class);
                        } else if ("float".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? float[].class : float.class);
                        } else if ("double".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? double[].class : double.class);
                        } else if ("boolean".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? boolean[].class : boolean.class);
                        } else if ("char".equals(paramType)) {
                            paramTypes[i] = (isArrayType ? char[].class : char.class);
                        } else {
                            throw new IllegalArgumentException("Invalid primitive type: '" + paramType + "'.");
                        }
                    } else {
                        if (isArrayType) {
                            paramTypes[i] = ClassUtil.forName("[L" + paramType + ";");
                        } else {
                            paramTypes[i] = ClassUtil.forName(paramType);
                        }
                    }
                }
            }

            return clazz.getMethod(methodName, paramTypes);
    }
    
}
