/*
 * 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.Method;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import freemarker.template.Configuration;
import freemarker.template.Version;

/**
 * A hack to keep some unit tests producing exactly the same results on Java 8 as on Java 5-7, by hiding members
 * added after Java 7.
 */
public class Java7MembersOnlyBeansWrapper extends BeansWrapper {
    
    private static final Set<String> POST_JAVA_7_MAP_METHODS = newHashSet(
            "compute", "computeIfAbsent", "computeIfPresent",
            "forEach", "getOrDefault", "merge", "putIfAbsent", "replace", "replaceAll");

    private static final Set<String> POST_JAVA_7_ITERABLE_METHODS = newHashSet("forEach");
    private static final Set<String> POST_JAVA_7_COLLECTION_METHODS = newHashSet("parallelStream", "removeIf", "stream");
    private static final Set<String> POST_JAVA_7_LIST_METHODS = newHashSet("sort", "spliterator");
    
    MethodAppearanceFineTuner POST_JAVA_7_FILTER = new MethodAppearanceFineTuner() {

        public void process(MethodAppearanceDecisionInput in, MethodAppearanceDecision out) {
            Method m = in.getMethod();
            Class declCl = m.getDeclaringClass();
            if (Map.class.isAssignableFrom(declCl)) {
                if (POST_JAVA_7_MAP_METHODS.contains(m.getName())) {
                    hideMember(out);
                    return;
                }
            }
            if (Iterable.class.isAssignableFrom(declCl)) {
                if (POST_JAVA_7_ITERABLE_METHODS.contains(m.getName())) {
                    hideMember(out);
                    return;
                }
            }
            if (Collection.class.isAssignableFrom(declCl)) {
                if (POST_JAVA_7_COLLECTION_METHODS.contains(m.getName())) {
                    hideMember(out);
                    return;
                }
            }
            if (List.class.isAssignableFrom(declCl)) {
                if (POST_JAVA_7_LIST_METHODS.contains(m.getName())) {
                    hideMember(out);
                    return;
                }
            }
        }

        private void hideMember(MethodAppearanceDecision out) {
            out.setExposeMethodAs(null);
            out.setExposeAsProperty(null);
        }
        
    };
    
    public Java7MembersOnlyBeansWrapper(Version version) {
        super(version);
        setMethodAppearanceFineTuner(POST_JAVA_7_FILTER);
    }

    private static <T> Set<T> newHashSet(T... items) {
        HashSet<T> r = new HashSet<>();
        for (T item : items) {
            r.add(item);
        }
        return r;
    }

    public Java7MembersOnlyBeansWrapper() {
        this(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
    }
    
}
