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

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import freemarker.template.Version;
import freemarker.template._TemplateAPI;
import freemarker.template.utility.ClassUtil;

/**
 * Legacy black list based member access policy, used only to keep old behavior, as it can't provide meaningful safety.
 * Do not use it if you allow untrusted users to edit templates!
 *
 * @since 2.3.30
 */
public final class DefaultMemberAccessPolicy implements MemberAccessPolicy {

    private static final String UNSAFE_METHODS_PROPERTIES = "unsafeMethods.properties";
    private static final Set<Method> UNSAFE_METHODS = createUnsafeMethodsSet();

    private static Set<Method> createUnsafeMethodsSet() {
        try {
            Properties props = ClassUtil.loadProperties(BeansWrapper.class, UNSAFE_METHODS_PROPERTIES);
            Set<Method> set = new HashSet<Method>(props.size() * 4 / 3, 1f);
            Map<String, Class<?>> primClasses = createPrimitiveClassesMap();
            for (Object key : props.keySet()) {
                try {
                    set.add(parseMethodSpec((String) key, primClasses));
                } catch (ClassNotFoundException e) {
                    if (ClassIntrospector.DEVELOPMENT_MODE) {
                        throw e;
                    }
                } catch (NoSuchMethodException e) {
                    if (ClassIntrospector.DEVELOPMENT_MODE) {
                        throw e;
                    }
                }
            }
            return set;
        } catch (Exception e) {
            throw new RuntimeException("Could not load unsafe method set", e);
        }
    }

    private static Method parseMethodSpec(String methodSpec, Map<String, Class<?>> primClasses)
    throws ClassNotFoundException,
        NoSuchMethodException {
        int brace = methodSpec.indexOf('(');
        int dot = methodSpec.lastIndexOf('.', brace);
        Class<?> clazz = ClassUtil.forName(methodSpec.substring(0, dot));
        String methodName = methodSpec.substring(dot + 1, brace);
        String argSpec = methodSpec.substring(brace + 1, methodSpec.length() - 1);
        StringTokenizer tok = new StringTokenizer(argSpec, ",");
        int argcount = tok.countTokens();
        Class<?>[] argTypes = new Class[argcount];
        for (int i = 0; i < argcount; i++) {
            String argClassName = tok.nextToken();
            argTypes[i] = primClasses.get(argClassName);
            if (argTypes[i] == null) {
                argTypes[i] = ClassUtil.forName(argClassName);
            }
        }
        return clazz.getMethod(methodName, argTypes);
    }

    private static Map<String, Class<?>> createPrimitiveClassesMap() {
        Map<String, Class<?>> map = new HashMap<String, Class<?>>();
        map.put("boolean", Boolean.TYPE);
        map.put("byte", Byte.TYPE);
        map.put("char", Character.TYPE);
        map.put("short", Short.TYPE);
        map.put("int", Integer.TYPE);
        map.put("long", Long.TYPE);
        map.put("float", Float.TYPE);
        map.put("double", Double.TYPE);
        return map;
    }

    private static final DefaultMemberAccessPolicy INSTANCE = new DefaultMemberAccessPolicy();

    private DefaultMemberAccessPolicy() {
    }

    /**
     * Returns the singleton that's compatible with the given incompatible improvements version.
     */
    public static DefaultMemberAccessPolicy getInstance(Version incompatibleImprovements) {
        _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements);
        // All breakpoints here must occur in ClassIntrospectorBuilder.normalizeIncompatibleImprovementsVersion!
        // Though currently we don't have any.
        return INSTANCE;
    }

    public ClassMemberAccessPolicy forClass(Class<?> containingClass) {
        return CLASS_MEMBER_ACCESS_POLICY_INSTANCE;
    }

    private static final BacklistClassMemberAccessPolicy CLASS_MEMBER_ACCESS_POLICY_INSTANCE
            = new BacklistClassMemberAccessPolicy();
    private static class BacklistClassMemberAccessPolicy implements ClassMemberAccessPolicy {

        public boolean isMethodExposed(Method method) {
            return !UNSAFE_METHODS.contains(method);
        }

        public boolean isConstructorExposed(Constructor<?> constructor) {
            return true;
        }

        public boolean isFieldExposed(Field field) {
            return true;
        }
    }
}
