/*
 * 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.proxy2.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.
 * 
 * @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;
    }
}
