/*
 * 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 org.apache.shiro.guice;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.inject.Binder;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matcher;
import com.google.inject.matcher.Matchers;
import com.google.inject.multibindings.MapBinder;
import com.google.inject.name.Names;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import com.google.inject.util.Types;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.SecurityUtils;

/**
 * TypeListener that injects setter methods on Shiro objects.
 */
class BeanTypeListener implements TypeListener {
    public static final Package SHIRO_GUICE_PACKAGE = ShiroModule.class.getPackage();
    public static final Package SHIRO_PACKAGE = SecurityUtils.class.getPackage();

    private static Matcher<Class> shiroMatcher = Matchers.inSubpackage(SHIRO_PACKAGE.getName());
    private static Matcher<Class> shiroGuiceMatcher = Matchers.inSubpackage(SHIRO_GUICE_PACKAGE.getName());

    private static Matcher<Class> classMatcher = ShiroMatchers.ANY_PACKAGE.and(shiroMatcher.and(Matchers.not(shiroGuiceMatcher)));

    public static final Matcher<TypeLiteral> MATCHER = ShiroMatchers.typeLiteral(classMatcher);

    private static final String BEAN_TYPE_MAP_NAME = "__SHIRO_BEAN_TYPES__";
    static final Key<?> MAP_KEY = Key.get(Types.mapOf(TypeLiteral.class, BeanTypeKey.class), Names.named(BEAN_TYPE_MAP_NAME));

    private static final Set<Class<?>> WRAPPER_TYPES = new HashSet<Class<?>>(Arrays.asList(
        Byte.class,
        Boolean.class,
        Character.class,
        Double.class,
        Float.class,
        Integer.class,
        Long.class,
        Short.class,
        Void.class));

    public <I> void hear(TypeLiteral<I> type, final TypeEncounter<I> encounter) {
        PropertyDescriptor propertyDescriptors[] = PropertyUtils.getPropertyDescriptors(type.getRawType());
        final Map<PropertyDescriptor, Key<?>> propertyDependencies = new HashMap<PropertyDescriptor, Key<?>>(propertyDescriptors.length);
        final Provider<Injector> injectorProvider = encounter.getProvider(Injector.class);
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            if (propertyDescriptor.getWriteMethod() != null && Modifier.isPublic(propertyDescriptor.getWriteMethod().getModifiers())) {
                Type propertyType = propertyDescriptor.getWriteMethod().getGenericParameterTypes()[0];
                propertyDependencies.put(propertyDescriptor, createDependencyKey(propertyDescriptor, propertyType));
            }
        }
        encounter.register(new MembersInjector<I>() {
            public void injectMembers(I instance) {
                for (Map.Entry<PropertyDescriptor, Key<?>> dependency : propertyDependencies.entrySet()) {
                    try {
                        final Injector injector = injectorProvider.get();

                        Object value = injector.getInstance(getMappedKey(injector, dependency.getValue()));
                        dependency.getKey().getWriteMethod().invoke(instance, value);

                    } catch (ConfigurationException e) {
                        // This is ok, it simply means that we can't fulfill this dependency.
                        // Is there a better way to do this?
                    } catch (InvocationTargetException e) {
                        throw new RuntimeException("Couldn't set property " + dependency.getKey().getDisplayName(), e);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException("We shouldn't have ever reached this point, we don't try to inject to non-accessible methods.", e);
                    }
                }

            }
        });
    }

    private static Key<?> getMappedKey(Injector injector, Key<?> key) {
        Map<TypeLiteral, BeanTypeKey> beanTypeMap = getBeanTypeMap(injector);
        if(key.getAnnotation() == null && beanTypeMap.containsKey(key.getTypeLiteral())) {
            return beanTypeMap.get(key.getTypeLiteral()).key;
        } else {
            return key;
        }
    }

    @SuppressWarnings({"unchecked"})
    private static Map<TypeLiteral, BeanTypeKey> getBeanTypeMap(Injector injector) {
        return (Map<TypeLiteral, BeanTypeKey>) injector.getInstance(MAP_KEY);
    }

    private static Key<?> createDependencyKey(PropertyDescriptor propertyDescriptor, Type propertyType) {
        if(requiresName(propertyType)) {
            return Key.get(propertyType, Names.named("shiro." + propertyDescriptor.getName()));
        } else {
            return Key.get(propertyType);
        }
    }

    private static boolean requiresName(Type propertyType) {
        if (propertyType instanceof Class) {
            Class<?> aClass = (Class<?>) propertyType;
            return aClass.isPrimitive() || aClass.isEnum() || WRAPPER_TYPES.contains(aClass) || CharSequence.class.isAssignableFrom(aClass);
        } else {
            return false;
        }
    }

    static void ensureBeanTypeMapExists(Binder binder) {
        beanTypeMapBinding(binder).addBinding(TypeLiteral.get(BeanTypeKey.class)).toInstance(new BeanTypeKey(null));
    }

    static <T> void bindBeanType(Binder binder, TypeLiteral<T> typeLiteral, Key<? extends T> key) {
        beanTypeMapBinding(binder).addBinding(typeLiteral).toInstance(new BeanTypeKey(key));
    }

    private static MapBinder<TypeLiteral, BeanTypeKey> beanTypeMapBinding(Binder binder) {
        return MapBinder.newMapBinder(binder, TypeLiteral.class, BeanTypeKey.class, Names.named(BEAN_TYPE_MAP_NAME));
    }

    private static class BeanTypeKey {
        Key<?> key;

        private BeanTypeKey(Key<?> key) {
            this.key = key;
        }
    }
}
