//  Copyright 2004 The Apache Software Foundation
//
// 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.apache.tapestry.enhance;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.ApplicationRuntimeException;
import org.apache.tapestry.IResourceResolver;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.IComponentClassEnhancer;
import org.apache.tapestry.enhance.javassist.EnhancedClassFactory;
import org.apache.tapestry.spec.IComponentSpecification;

/**
 *  Default implementation of {@link IComponentClassEnhancer}.
 *
 *  @author Howard Lewis Ship
 *  @version $Id$
 *  @since 3.0
 * 
 **/

public class DefaultComponentClassEnhancer implements IComponentClassEnhancer
{
    private static final Log LOG = LogFactory.getLog(DefaultComponentClassEnhancer.class);

    /**
     *  Map of Class, keyed on IComponentSpecification.
     * 
     **/

    private Map _cachedClasses;
    private IResourceResolver _resolver;
    private IEnhancedClassFactory _factory;
    private boolean _disableValidation;

    /**
     * @param resolver resource resolver used to locate classes
     * @param disableValidation if true, then validation (of unimplemented abstract methods)
     * is skipped
     */
    public DefaultComponentClassEnhancer(IResourceResolver resolver, boolean disableValidation)
    {
        _cachedClasses = Collections.synchronizedMap(new HashMap());
        _resolver = resolver;
        _factory = createEnhancedClassFactory();
        _disableValidation = disableValidation;
    }

    protected IEnhancedClassFactory createEnhancedClassFactory()
    {
        return new EnhancedClassFactory(getResourceResolver());
    }

    public synchronized void reset()
    {
        _cachedClasses.clear();
        _factory.reset();
    }

    public IResourceResolver getResourceResolver()
    {
        return _resolver;
    }

    public Class getEnhancedClass(IComponentSpecification specification, String className)
    {
            synchronized (specification)
            {
                Class result = getCachedClass(specification);

                if (result == null)
                {
                    result = constructComponentClass(specification, className);
                    storeCachedClass(specification, result);
                }

                return result;
            }
    }

    protected void storeCachedClass(IComponentSpecification specification, Class cachedClass)
    {
        _cachedClasses.put(specification, cachedClass);
    }

    protected Class getCachedClass(IComponentSpecification specification)
    {
        return (Class) _cachedClasses.get(specification);
    }

    /**
     *  Returns the class to be used for the component, which is either
     *  the class with the given name, or an enhanced subclass.
     * 
     **/

    protected Class constructComponentClass(
        IComponentSpecification specification,
        String className)
    {
        Class result = null;

        try
        {
            result = _resolver.findClass(className);
        }
        catch (Exception ex)
        {
            throw new ApplicationRuntimeException(ex.getMessage(), specification.getLocation(), ex);
        }

        try
        {
            ComponentClassFactory factory = createComponentClassFactory(specification, result);

            if (factory.needsEnhancement())
            {
                result = factory.createEnhancedSubclass();

                if (!_disableValidation)
                    validateEnhancedClass(result, className, specification);
            }
        }
        catch (CodeGenerationException e)
        {
            throw new ApplicationRuntimeException(
                Tapestry.format("ComponentClassFactory.code-generation-error", className),
                e);
        }

        return result;
    }

    /**
     *  Constructs a new factory for enhancing the specified class. Advanced users
     *  may want to provide thier own enhancements to classes and this method
     *  is the hook that allows them to provide a subclass of
     *  {@link org.apache.tapestry.enhance.ComponentClassFactory} adding those
     *  enhancements.
     * 
     **/

    protected ComponentClassFactory createComponentClassFactory(
        IComponentSpecification specification,
        Class componentClass)
    {
        return new ComponentClassFactory(_resolver, specification, componentClass, _factory);
    }

    /**
     *  Invoked to validate that an enhanced class is acceptible.  Primarily, this is to ensure
     *  that the class contains no unimplemented abstract methods or fields.  Normally,
     *  this kind of checking is done at compile time, but for generated
     *  classes, there is no compile time check (!) and you can get runtime
     *  errors when accessing unimplemented abstract methods.
     * 
     *
     **/

    protected void validateEnhancedClass(
        Class subject,
        String className,
        IComponentSpecification specification)
    {
        boolean debug = LOG.isDebugEnabled();

        if (debug)
            LOG.debug("Validating " + subject);

        Set implementedMethods = new HashSet();
        Class current = subject;

        while (true)
        {
            Method m = checkForAbstractMethods(current, implementedMethods);

            if (m != null)
                throw new ApplicationRuntimeException(
                    Tapestry.format(
                        "DefaultComponentClassEnhancer.no-impl-for-abstract-method",
                        new Object[] { m, current, className, subject.getName()}),
                    specification.getLocation(),
                    null);

            // An earlier version of this code walked the interfaces directly,
            // but it appears that implementing an interface actually
            // puts abstract method declarations into the class
            // (at least, in terms of what getDeclaredMethods() returns).

            // March up to the super class.

            current = current.getSuperclass();

            // Once advanced up to a concrete class, we trust that
            // the compiler did its checking.

            if (!Modifier.isAbstract(current.getModifiers()))
                break;
        }

    }

    /**
     *  Searches the class for abstract methods, returning the first found.
     *  Records non-abstract methods in the implementedMethods set.
     * 
     **/

    private Method checkForAbstractMethods(Class current, Set implementedMethods)
    {
        boolean debug = LOG.isDebugEnabled();

        if (debug)
            LOG.debug("Searching for abstract methods in " + current);

        Method[] methods = current.getDeclaredMethods();

        for (int i = 0; i < methods.length; i++)
        {
            Method m = methods[i];

            if (debug)
                LOG.debug("Checking " + m);

            boolean isAbstract = Modifier.isAbstract(m.getModifiers());

            MethodSignature s = new MethodSignature(m);

            if (isAbstract)
            {
                if (implementedMethods.contains(s))
                    continue;

                return m;
            }

            implementedMethods.add(s);
        }

        return null;
    }

}