/*
 * 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.commons.proxy.impl;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * A cache for storing implementation classes for proxies based on a specific type of {@link ProxyClassGenerator}.  A
 * proxy class cache ensures that there is only one class for every
 * {@link ProxyClassGenerator}/{@link ClassLoader}/proxy class array combination.
 *
 * @author James Carman
 * @since 1.0
 */
public class ProxyClassCache
{

//**********************************************************************************************************************
// Fields
//**********************************************************************************************************************

    private final Map<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>> loaderToClassCache
            = new WeakHashMap<ClassLoader, Map<Set<Class<?>>, WeakReference<Class<?>>>>();
    private final ProxyClassGenerator proxyClassGenerator;

  //**********************************************************************************************************************
 // Constructors
 //**********************************************************************************************************************

    /**
     * Create a new ProxyClassCache instance.
     * @param proxyClassGenerator
     */
    public ProxyClassCache( ProxyClassGenerator proxyClassGenerator )
    {
        this.proxyClassGenerator = proxyClassGenerator;
    }

//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************

    private Map<Set<Class<?>>, WeakReference<Class<?>>> getClassCache( ClassLoader classLoader )
    {
        Map<Set<Class<?>>, WeakReference<Class<?>>> cache = loaderToClassCache.get(classLoader);
        if( cache == null )
        {
            cache = new HashMap<Set<Class<?>>, WeakReference<Class<?>>>();
            loaderToClassCache.put(classLoader, cache);
        }
        return cache;
    }

    private Set<Class<?>> toClassCacheKey( Class<?>[] proxyClasses )
    {
        return new HashSet<Class<?>>(Arrays.asList(proxyClasses));
    }

    /**
     * Returns the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
     * array of proxy classes.
     *
     * @param classLoader  the classloader
     * @param proxyClasses the proxy classes
     * @return the proxy class generated by the {@link ProxyClassGenerator} using the specified {@link ClassLoader} and
     *         array of proxy classes
     */
    public synchronized Class<?> getProxyClass( ClassLoader classLoader, Class<?>[] proxyClasses )
    {
        final Map<Set<Class<?>>, WeakReference<Class<?>>> classCache = getClassCache(classLoader);
        final Set<Class<?>> key = toClassCacheKey(proxyClasses);
        Class<?> proxyClass;
        Reference<Class<?>> proxyClassReference = classCache.get(key);
        if( proxyClassReference == null )
        {
            proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
            classCache.put(key, new WeakReference<Class<?>>(proxyClass));
        }
        else
        {
            synchronized( proxyClassReference )
            {
                proxyClass = proxyClassReference.get();
                if( proxyClass == null )
                {
                    proxyClass = proxyClassGenerator.generateProxyClass(classLoader, proxyClasses);
                    classCache.put(key, new WeakReference<Class<?>>(proxyClass));
                }
            }
        }
        return proxyClass;
    }
}
