package org.apache.commons.ognl;

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

import org.apache.commons.ognl.internal.*;
import org.apache.commons.ognl.internal.entry.*;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.Permission;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This class takes care of all the internal caching for OGNL.
 */
public class OgnlCache {

    private final CacheFactory cacheFactory = new HashMapCacheFactory();

    private final ClassCache<MethodAccessor> methodAccessors = cacheFactory.createClassCache();
    {
        MethodAccessor methodAccessor = new ObjectMethodAccessor();
        setMethodAccessor( Object.class, methodAccessor );
        setMethodAccessor( byte[].class, methodAccessor );
        setMethodAccessor( short[].class, methodAccessor );
        setMethodAccessor( char[].class, methodAccessor );
        setMethodAccessor( int[].class, methodAccessor );
        setMethodAccessor( long[].class, methodAccessor );
        setMethodAccessor( float[].class, methodAccessor );
        setMethodAccessor( double[].class, methodAccessor );
        setMethodAccessor( Object[].class, methodAccessor );
    }

    private final ClassCache<PropertyAccessor> propertyAccessors = cacheFactory.createClassCache();
    {
        PropertyAccessor propertyAccessor = new ArrayPropertyAccessor();
        setPropertyAccessor( Object.class, new ObjectPropertyAccessor() );
        setPropertyAccessor( byte[].class, propertyAccessor );
        setPropertyAccessor( short[].class, propertyAccessor );
        setPropertyAccessor( char[].class, propertyAccessor );
        setPropertyAccessor( int[].class, propertyAccessor );
        setPropertyAccessor( long[].class, propertyAccessor );
        setPropertyAccessor( float[].class, propertyAccessor );
        setPropertyAccessor( double[].class, propertyAccessor );
        setPropertyAccessor( Object[].class, propertyAccessor );
        setPropertyAccessor( List.class, new ListPropertyAccessor() );
        setPropertyAccessor( Map.class, new MapPropertyAccessor() );
        setPropertyAccessor( Set.class, new SetPropertyAccessor() );
        setPropertyAccessor( Iterator.class, new IteratorPropertyAccessor() );
        setPropertyAccessor( Enumeration.class, new EnumerationPropertyAccessor() );
    }

    private final ClassCache<ElementsAccessor> elementsAccessors = cacheFactory.createClassCache();
    {
        ElementsAccessor elementsAccessor = new ArrayElementsAccessor();
        setElementsAccessor( Object.class, new ObjectElementsAccessor() );
        setElementsAccessor( byte[].class, elementsAccessor );
        setElementsAccessor( short[].class, elementsAccessor );
        setElementsAccessor( char[].class, elementsAccessor );
        setElementsAccessor( int[].class, elementsAccessor );
        setElementsAccessor( long[].class, elementsAccessor );
        setElementsAccessor( float[].class, elementsAccessor );
        setElementsAccessor( double[].class, elementsAccessor );
        setElementsAccessor( Object[].class, elementsAccessor );
        setElementsAccessor( Collection.class, new CollectionElementsAccessor() );
        setElementsAccessor( Map.class, new MapElementsAccessor() );
        setElementsAccessor( Iterator.class, new IteratorElementsAccessor() );
        setElementsAccessor( Enumeration.class, new EnumerationElementsAccessor() );
        setElementsAccessor( Number.class, new NumberElementsAccessor() );
    }

    private final ClassCache<NullHandler> nullHandlers = cacheFactory.createClassCache( );
    {
        NullHandler nullHandler = new ObjectNullHandler();
        setNullHandler( Object.class, nullHandler );
        setNullHandler( byte[].class, nullHandler );
        setNullHandler( short[].class, nullHandler );
        setNullHandler( char[].class, nullHandler );
        setNullHandler( int[].class, nullHandler );
        setNullHandler( long[].class, nullHandler );
        setNullHandler( float[].class, nullHandler );
        setNullHandler( double[].class, nullHandler );
        setNullHandler( Object[].class, nullHandler );
    }

    final ClassCache<Map<String, PropertyDescriptor>> propertyDescriptorCache =
        cacheFactory.createClassCache( new PropertyDescriptorCacheEntryFactory() );

    private final ClassCache<List<Constructor<?>>> constructorCache =
        cacheFactory.createClassCache(key -> Arrays.<Constructor<?>>asList( key.getConstructors() ));

    private final Cache<DeclaredMethodCacheEntry, Map<String, List<Method>>> _methodCache =
        cacheFactory.createCache( new DeclaredMethodCacheEntryFactory() );

    private final Cache<PermissionCacheEntry, Permission> _invokePermissionCache =
        cacheFactory.createCache( new PermissionCacheEntryFactory() );

    private final ClassCache<Map<String, Field>> _fieldCache =
        cacheFactory.createClassCache( new FieldCacheEntryFactory() );

    private final Cache<Method, Class<?>[]> _methodParameterTypesCache =
        cacheFactory.createCache(Method::getParameterTypes);

    private final Cache<GenericMethodParameterTypeCacheEntry, Class<?>[]> _genericMethodParameterTypesCache =
        cacheFactory.createCache( new GenericMethodParameterTypeFactory() );

    private final Cache<Constructor<?>, Class<?>[]> _ctorParameterTypesCache =
        cacheFactory.createCache(Constructor::getParameterTypes);

    private final Cache<Method, MethodAccessEntryValue> _methodAccessCache =
        cacheFactory.createCache( new MethodAccessCacheEntryFactory( ) );

    private final MethodPermCacheEntryFactory methodPermCacheEntryFactory =
        new MethodPermCacheEntryFactory( System.getSecurityManager() );

    private final Cache<Method, Boolean> _methodPermCache = cacheFactory.createCache( methodPermCacheEntryFactory );

    public Class<?>[] getMethodParameterTypes( Method method ) throws CacheException {
        return _methodParameterTypesCache.get( method );
    }

    public Class<?>[] getParameterTypes( Constructor<?> constructor ) throws CacheException {
        return _ctorParameterTypesCache.get( constructor );
    }

    public List<Constructor<?>> getConstructor( Class<?> clazz ) throws CacheException {
        return constructorCache.get( clazz );
    }

    public Map<String, Field> getField( Class<?> clazz ) throws CacheException {
        return _fieldCache.get( clazz );
    }

    public Map<String, List<Method>> getMethod( DeclaredMethodCacheEntry declaredMethodCacheEntry ) throws CacheException {
        return _methodCache.get( declaredMethodCacheEntry );
    }

    public Map<String, PropertyDescriptor> getPropertyDescriptor( Class<?> clazz ) throws CacheException {
        return propertyDescriptorCache.get( clazz );
    }

    public Permission getInvokePermission( PermissionCacheEntry permissionCacheEntry ) throws CacheException {
        return _invokePermissionCache.get( permissionCacheEntry );
    }

    public MethodAccessor getMethodAccessor( Class<?> clazz ) throws OgnlException
    {
        MethodAccessor methodAccessor = ClassCacheHandler.getHandler( clazz, methodAccessors );
        if ( methodAccessor != null )
        {
            return methodAccessor;
        }
        throw new OgnlException( "No method accessor for " + clazz );
    }

    public void setMethodAccessor( Class<?> clazz, MethodAccessor accessor )
    {
        methodAccessors.put( clazz, accessor );
    }

    public void setPropertyAccessor( Class<?> clazz, PropertyAccessor accessor )
    {
        propertyAccessors.put( clazz, accessor );
    }

    public PropertyAccessor getPropertyAccessor( Class<?> clazz )
        throws OgnlException
    {
        PropertyAccessor propertyAccessor = ClassCacheHandler.getHandler( clazz, propertyAccessors );
        if ( propertyAccessor != null )
        {
            return propertyAccessor;
        }
        throw new OgnlException( "No property accessor for class " + clazz );
    }

    /**
     * Registers the specified {@link ClassCacheInspector} with all class reflection based internal caches. This may
     * have a significant performance impact so be careful using this in production scenarios.
     *
     * @param inspector The inspector instance that will be registered with all internal cache instances.
     */
    public void setClassCacheInspector( ClassCacheInspector inspector )
    {
        propertyDescriptorCache.setClassInspector( inspector );
        constructorCache.setClassInspector( inspector );
        //TODO: methodCache and invokePC should allow to use classCacheInsecptor
//        _methodCache.setClassInspector( inspector );
//        _invokePermissionCache.setClassInspector( inspector );
        _fieldCache.setClassInspector( inspector );
    }

    public Class<?>[] getGenericMethodParameterTypes( GenericMethodParameterTypeCacheEntry key )
        throws CacheException
    {
        return _genericMethodParameterTypesCache.get( key );
    }

    public boolean getMethodPerm( Method method ) throws CacheException
    {
        return _methodPermCache.get( method );
    }

    public MethodAccessEntryValue getMethodAccess( Method method ) throws CacheException
    {
        return _methodAccessCache.get( method );
    }

    public void clear() {
        _methodParameterTypesCache.clear();
        _ctorParameterTypesCache.clear();
        propertyDescriptorCache.clear();
        constructorCache.clear();
        _methodCache.clear();
        _invokePermissionCache.clear();
        _fieldCache.clear();
        _methodAccessCache.clear();
    }

    public ElementsAccessor getElementsAccessor( Class<?> clazz ) throws OgnlException
    {
        ElementsAccessor answer = ClassCacheHandler.getHandler( clazz, elementsAccessors );
        if ( answer != null )
        {
            return answer;
        }
        throw new OgnlException( "No elements accessor for class " + clazz );
    }

    public void setElementsAccessor( Class<?> clazz, ElementsAccessor accessor )
    {
        elementsAccessors.put( clazz, accessor );
    }

    public NullHandler getNullHandler( Class<?> clazz ) throws OgnlException
    {
        NullHandler answer = ClassCacheHandler.getHandler( clazz, nullHandlers );
        if ( answer != null )
        {
            return answer;
        }
        throw new OgnlException( "No null handler for class " + clazz );
    }

    public void setNullHandler( Class<?> clazz, NullHandler handler )
    {
        nullHandlers.put( clazz, handler );
    }

    public void setSecurityManager( SecurityManager securityManager )
    {
        methodPermCacheEntryFactory.setSecurityManager( securityManager );
    }
}
