/*
 * Copyright 2003-2007 the original author or authors.
 *
 * Licensed 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.codehaus.groovy.runtime.metaclass;

import groovy.lang.*;
import org.codehaus.groovy.classgen.ReflectorGenerator;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.CachedMethod;
import org.codehaus.groovy.reflection.FastArray;
import org.codehaus.groovy.reflection.ReflectionCache;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods;
import org.codehaus.groovy.runtime.Reflector;
import org.objectweb.asm.ClassWriter;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;

/**
 * A registry of MetaClass instances which caches introspection &
 * reflection information and allows methods to be dynamically added to
 * existing classes at runtime
 *
 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
 * @author John Wilson
 * @author <a href="mailto:blackdrag@gmx.org">Jochen Theodorou</a>
 * @author Graeme Rocher
 *
 * @version $Revision$
 */
public class MetaClassRegistryImpl implements MetaClassRegistry{
    private volatile int constantMetaClassCount = 0;
    private ConcurrentReaderHashMap constantMetaClasses = new ConcurrentReaderHashMap();
    private MemoryAwareConcurrentReadMap weakMetaClasses = new MemoryAwareConcurrentReadMap();
    private MemoryAwareConcurrentReadMap loaderMap = new MemoryAwareConcurrentReadMap();
    private boolean useAccessible;
    
    private FastArray instanceMethods = new FastArray();
    private FastArray staticMethods = new FastArray();

    public static final int LOAD_DEFAULT = 0;
    public static final int DONT_LOAD_DEFAULT = 1;
    private static MetaClassRegistry instanceInclude;
    private static MetaClassRegistry instanceExclude;

    public MetaClassRegistryImpl() {
        this(LOAD_DEFAULT, true);
    }

    public MetaClassRegistryImpl(int loadDefault) {
        this(loadDefault, true);
    }

    /**
     * @param useAccessible defines whether or not the {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)}
     *                      method will be called to enable access to all methods when using reflection
     */
    public MetaClassRegistryImpl(boolean useAccessible) {
        this(LOAD_DEFAULT, useAccessible);
    }
    
    public MetaClassRegistryImpl(final int loadDefault, final boolean useAccessible) {
        this.useAccessible = useAccessible;

        if (loadDefault == LOAD_DEFAULT) {
            HashMap map = new HashMap();

            // lets register the default methods
            registerMethods(DefaultGroovyMethods.class, true, map);
            registerMethods(DefaultGroovyStaticMethods.class, false, map);

            for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) {
                Map.Entry e = (Map.Entry) it.next();
                CachedClass cls = (CachedClass) e.getKey();
                ArrayList list = (ArrayList) e.getValue();
                cls.setNewMopMethods(list);
            }
        }

        installMetaClassCreationHandle();

        final MetaClass emcMetaClass = getMetaClassFor(ExpandoMetaClass.class);
        emcMetaClass.initialize();
        constantMetaClasses.put(ExpandoMetaClass.class,emcMetaClass);
        constantMetaClassCount = 1;


   }

    /**
     * Looks for a class called 'groovy.runtime.metaclass.CustomMetaClassCreationHandle' and if it exists uses it as the MetaClassCreationHandle
     * otherwise uses the default
     *
     * @see groovy.lang.MetaClassRegistry.MetaClassCreationHandle
     */
    private void installMetaClassCreationHandle() {
	       try {
	           final Class customMetaClassHandle = Class.forName("groovy.runtime.metaclass.CustomMetaClassCreationHandle");
	           final Constructor customMetaClassHandleConstructor = customMetaClassHandle.getConstructor(new Class[]{});
				 this.metaClassCreationHandle = (MetaClassCreationHandle)customMetaClassHandleConstructor.newInstance(new Object[]{});
	       } catch (final ClassNotFoundException e) {
	           this.metaClassCreationHandle = new MetaClassCreationHandle();
	       } catch (final Exception e) {
	           throw new GroovyRuntimeException("Could not instantiate custom Metaclass creation handle: "+ e, e);
	       }
    }
    
    private void registerMethods(final Class theClass, final boolean useInstanceMethods, Map map) {
        CachedMethod[] methods = ReflectionCache.getCachedClass(theClass).getMethods();

        for (int i = 0; i < methods.length; i++) {
            CachedMethod method = methods[i];
            final int mod = method.getModifiers();
            if (Modifier.isStatic(mod) && Modifier.isPublic(mod)) {
                CachedClass[] paramTypes = method.getParameterTypes();
                if (paramTypes.length > 0) {
                    ArrayList arr = (ArrayList) map.get(paramTypes[0]);
                    if (arr == null) {
                        arr = new ArrayList(4);
                        map.put(paramTypes[0],arr);
                    }
                    if (useInstanceMethods) {
                        final NewInstanceMetaMethod metaMethod = new NewInstanceMetaMethod(method);
                        arr.add(metaMethod);
                        instanceMethods.add(metaMethod);
                    } else {
                        final NewStaticMetaMethod metaMethod = new NewStaticMetaMethod(method);
                        arr.add(metaMethod);
                        staticMethods.add(metaMethod);
                    }
                }
            }
        }
    }

    public MetaClass getMetaClass(Class theClass) {
        MetaClass answer=null;
        if (constantMetaClassCount!=0) answer = (MetaClass) constantMetaClasses.get(theClass);
        if (answer!=null) return answer;
        answer = (MetaClass) weakMetaClasses.get(theClass);
        if (answer!=null) return answer;

        synchronized (theClass) {
            answer = (MetaClass) weakMetaClasses.get(theClass);
            if (answer!=null) return answer;
            
            answer = getMetaClassFor(theClass);
            answer.initialize();
            if (GroovySystem.isKeepJavaMetaClasses()) {
                constantMetaClassCount++;
                constantMetaClasses.put(theClass,answer);
            } else {
                weakMetaClasses.put(theClass, answer);
            }
            return answer;
        }
    }

    public void removeMetaClass(Class theClass) {
        Object answer=null;
        if (constantMetaClassCount!=0) answer = constantMetaClasses.remove(theClass);
        if (answer==null) {
            weakMetaClasses.remove(theClass);
        } else {
            synchronized(theClass) {
                constantMetaClassCount--;
            }
        }
    }

    /**
     * Registers a new MetaClass in the registry to customize the type
     *
     * @param theClass
     * @param theMetaClass
     */
    public void setMetaClass(Class theClass, MetaClass theMetaClass) {
        synchronized(theClass) {
            constantMetaClassCount++;
            constantMetaClasses.put(theClass, theMetaClass);
        }
    }

    public boolean useAccessible() {
        return useAccessible;
    }

    /**
     * create Reflector loader instance if not in map. This method
     * is only used with a lock on "this" and since loaderMap is not
     * used anywhere else no sync is needed here
     */
    private ReflectorLoader getReflectorLoader(final ClassLoader loader) {
        ReflectorLoader reflectorLoader = (ReflectorLoader) loaderMap.get(loader);
        if (reflectorLoader == null) {
            reflectorLoader = (ReflectorLoader) AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    return new ReflectorLoader(loader);
                }
            }); 
            loaderMap.put(loader, reflectorLoader);
        }
        return reflectorLoader;
    }

    /**
     * Find a MetaClass for the class
     * Use the MetaClass of the superclass of the class to create the MetaClass
     * 
     * @param theClass
     * @return An instance of the MetaClass which will handle this class
     */
    private MetaClass getMetaClassFor(final Class theClass) {
        return metaClassCreationHandle.create(theClass,this);
    }

    // the following is experimental code, not intended for stable use yet
    private MetaClassCreationHandle metaClassCreationHandle = new MetaClassCreationHandle();
    /**
     * Gets a handle internally used to create MetaClass implementations
     * WARNING: experimental code, likely to change soon
     * @return the handle
     */
    public MetaClassCreationHandle getMetaClassCreationHandler() {
        return metaClassCreationHandle;
    }
    /**
     * Sets a handle internally used to create MetaClass implementations.
     * When replacing the handle with a custom version, you should
     * resuse the old handle to keep custom logic and to use the
     * default logic as fallback.
     * WARNING: experimental code, likely to change soon
     * @param handle the handle
     */
    public void setMetaClassCreationHandle(MetaClassCreationHandle handle) {
		if(handle == null) throw new IllegalArgumentException("Cannot set MetaClassCreationHandle to null value!");
        metaClassCreationHandle = handle;
    }    

    /**
     * Singleton of MetaClassRegistry. Shall we use threadlocal to store the instance?
     *
     * @param includeExtension
     */
    public static MetaClassRegistry getInstance(int includeExtension) {
        if (includeExtension != DONT_LOAD_DEFAULT) {
            if (instanceInclude == null) {
                instanceInclude = new MetaClassRegistryImpl();
            }
            return instanceInclude;
        }
        else {
            if (instanceExclude == null) {
                instanceExclude = new MetaClassRegistryImpl(DONT_LOAD_DEFAULT);
            }
            return instanceExclude;
        }
    }

    public synchronized Reflector loadReflector(final Class theClass, List methods) {
        final String name = getReflectorName(theClass);
        ClassLoader loader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
        ClassLoader loader = theClass.getClassLoader();
        if (loader == null) loader = this.getClass().getClassLoader();
                return loader;
            }
        });
        final ReflectorLoader rloader = getReflectorLoader(loader);
        Class ref = rloader.getLoadedClass(name);
        if (ref == null) {
            /*
             * Lets generate it && load it.
             */                        
            ReflectorGenerator generator = new ReflectorGenerator(methods);
            ClassWriter cw = new ClassWriter(true);
            generator.generate(cw, name);
            final byte[] bytecode = cw.toByteArray();
            ref = (Class) AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    return rloader.defineClass(name, bytecode, getClass().getProtectionDomain());
        }
            });
        }
        try {
          return (Reflector) ref.newInstance();
        } catch (Exception e) {
            return null;
        }
    }

    private String getReflectorName(Class theClass) {
        String className = theClass.getName();
        String packagePrefix = "gjdk.";
        String name = packagePrefix + className + "_GroovyReflector";
        if (theClass.isArray()) {
               Class clazz = theClass;
               name = packagePrefix;
               int level = 0;
               while (clazz.isArray()) {
                  clazz = clazz.getComponentType();
                  level++;
               }
            String componentName = clazz.getName();
            name = packagePrefix + componentName + "_GroovyReflectorArray";
            if (level>1) name += level;
        }
        return name;
    }

    public FastArray getInstanceMethods() {
        return instanceMethods;
    }

    public FastArray getStaticMethods() {
        return staticMethods;
    }
}
