/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
import org.eclipse.jem.internal.proxy.core.IConfigurationContributor;
import org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory;
import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry;
import org.eclipse.jem.internal.proxy.ide.IDERegistration;
import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorTypeInfo;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.BeanProxyWrapper;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.ProxyException;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigManager;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentType;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterType;
import org.eclipse.jst.jsf.facesconfig.emf.ValidatorType;

/**
 * Utility class for finding and bean introspecting component and related
 * classes.
 * 
 * @author cbateman
 * 
 */
public final class DTComponentIntrospector
{
    /**
     * A shared type cache for doing tag class introspection. The cache stores
     * type hierarchies and updates them on detected changes to reduce the
     * overhead of doing such lookups
     */
    private static TypeInfoCache TYPE_CACHE; // lazily created, don't access

    // directly

    /**
     * @return the type cache used by all DTComponentIntrospector internally.
     */
    public static TypeInfoCache getSharedTypeCache()
    {
        if (TYPE_CACHE == null)
        {
            TYPE_CACHE = TypeInfoCache.createNewInstance();
        }
        return TYPE_CACHE;
    }

    /**
     * @param classType
     * @param className
     * @param project
     * @param contributors  may be null
     * @return the component type info for the class type or null if none.  Adds
     * contributors to the class path
     */
    public static ComponentTypeInfo getComponent(final String classType,
            final String className, final IProject project,
            final IConfigurationContributor[] contributors)
    {
        ProxyFactoryRegistry registry = null;
        try
        {
            registry = getProxyFactoryRegistry(project,
                    contributors);
    
            if (registry != null)
            {
                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
                final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                        classTypeProxy);
    
                String family = null;
                String renderer = null;
                try
                {
                    classTypeWrapper.init();
                    family = classTypeWrapper.callStringMethod("getFamily"); //$NON-NLS-1$
                    renderer = classTypeWrapper.callStringMethod("getRendererType"); //$NON-NLS-1$
                }
                catch (ProxyException e1)
                {
                    // fall through
                    if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                    {
                        JSFCoreTraceOptions.log("DTComponentIntrospector.getComponent:", e1); //$NON-NLS-1$
                    }
                }
    
                IType type = null;
    
                try
                {
                    type = JavaCore.create(project).findType(className);
                }
                catch (JavaModelException e)
                {
                    // fall through;
                }
    
                List<String> interfaces = new ArrayList<String>();
                List<String> superClasses = new ArrayList<String>();
    
                if (type != null)
                {
                    TypeInfoCache typeCache = getSharedTypeCache();
    
                    IType[] interfaceTypes = typeCache.cacheInterfaceTypesFor(type);
                    for (IType interfaze : interfaceTypes)
                    {
                        interfaces.add(interfaze.getFullyQualifiedName());
                    }
    
                    IType[] superClassTypes = typeCache.cacheSupertypesFor(type);
    
                    for (IType superClass : superClassTypes)
                    {
                        superClasses.add(superClass.getFullyQualifiedName());
                    }
                }
    
                return new ComponentTypeInfo(classType, className, superClasses
                        .toArray(new String[0]), interfaces.toArray(new String[0]),
                        family, renderer);
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;
    }

    /**
     * @param classType
     * @param className
     * @param project
     * @return the component type info with no additional classpath
     *         contributions. May return null;
     */
    public static ComponentTypeInfo getComponent(final String classType,
            final String className, final IProject project)
    {
        return getComponent(classType, className, project, null);
    }

    /**
     * @param converterId
     * @param converterClass
     * @return a new converter type info for the converter id.
     */
    public static ConverterTypeInfo getConverter(final String converterId,
            final String converterClass)
    {
        return new ConverterTypeInfo(converterClass, converterId);
    }

    /**
     * @param validatorId
     * @param validatorClass
     * @return a new validator type info for the validator id
     */
    public static ValidatorTypeInfo getValidator(final String validatorId,
            final String validatorClass)
    {
        return new ValidatorTypeInfo(validatorClass, validatorId);
    }

    /**
     * @param componentType
     * @param project
     * @return the configured class name for the JSF component type id or null
     *         if not found.
     */
    public static String findComponentClass(final String componentType,
            final IProject project)
    {
        final JSFAppConfigManager manager = JSFAppConfigManager
                .getInstance(project);
        final List components = manager.getComponents();

        for (final Iterator it = components.iterator(); it.hasNext();)
        {
            final ComponentType component = (ComponentType) it.next();
            final String type = component.getComponentType().getTextContent()
                    .trim();

            if (componentType.equals(type))
            {
                return component.getComponentClass().getTextContent().trim();
            }
        }
        return null;
    }

    /**
     * @param converterId
     * @param project
     * @return a fully qualified class name corresponding to converterId or null
     *         if none.
     */
    public static String findConverterClass(final String converterId,
            final IProject project)
    {
        final JSFAppConfigManager manager = JSFAppConfigManager
                .getInstance(project);
        final List converters = manager.getConverters();

        for (final Iterator it = converters.iterator(); it.hasNext();)
        {
            final ConverterType converter = (ConverterType) it.next();

            if (converter != null && converter.getConverterId() != null
                    && converter.getConverterId().getTextContent() != null)
            {
                final String type = converter.getConverterId().getTextContent()
                        .trim();

                if (converterId.equals(type))
                {
                    if (converter.getConverterClass() != null && converter.getConverterClass().getTextContent()!=null)
                    {
                        return converter.getConverterClass().getTextContent()
                                .trim();
                    }
                    return null;
                }
            }
        }
        return null;
    }

    /**
     * @param validatorId
     * @param project
     * @return a fully qualified class name corresponding to the validatorId or
     *         null if none.
     */
    public static String findValidatorClass(final String validatorId,
            final IProject project)
    {
        final JSFAppConfigManager manager = JSFAppConfigManager
                .getInstance(project);
        final List converters = manager.getValidators();

        for (final Iterator it = converters.iterator(); it.hasNext();)
        {
            final ValidatorType validatorType = (ValidatorType) it.next();
            
            if (validatorType != null && validatorType.getValidatorId() != null && 
                    validatorType.getValidatorId().getTextContent() != null)
            {
                final String type = validatorType.getValidatorId().getTextContent()
                        .trim();
    
                if (validatorId.equals(type))
                {
                    return validatorType.getValidatorClass().getTextContent()
                            .trim();
                }
            }
        }
        return null;
    }

    /**
     * @param type
     * @param checkInstanceOf
     * @return true if type resolves to a type that is an instance of one of the
     *         types in checkInstanceOf.
     */
    public static boolean isTypeNameInstanceOfClass(final IType type,
            final Set<String> checkInstanceOf)
    {
        if (type != null)
        {
            // first and foremost, are these exactly droids you're
            // looking for and not just their predecessors?
            if (checkInstanceOf.contains(type.getFullyQualifiedName()))
            {
                return true;
            }

            for (final IType supertype : getSharedTypeCache()
                    .cacheSupertypesFor(type))
            {
                if (checkInstanceOf.contains(supertype.getFullyQualifiedName()))
                {
                    return true;
                }
            }

            for (final IType interfaces : getSharedTypeCache()
                    .cacheInterfaceTypesFor(type))
            {
                if (checkInstanceOf
                        .contains(interfaces.getFullyQualifiedName()))
                {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * @param typeInfo
     * @param project
     * @return a list of all bean properties (using the POJO method) on
     *         typeInfo. List may be empty, never null.
     */
    public static Map<String, JDTBeanProperty> getBeanProperties(
            final ComponentTypeInfo typeInfo, final IProject project)
    {
        Map<String, JDTBeanProperty> properties = new HashMap<String, JDTBeanProperty>();

        IJavaProject javaProject = JavaCore.create(project);
        try
        {
            IType type = javaProject.findType(typeInfo.getClassName());

            if (type != null)
            {
                // TODO: should be able to use type cache for this
                final JDTBeanIntrospector introspector = new JDTBeanIntrospector(
                        type);
                properties = introspector.getProperties();
            }
        }
        catch (JavaModelException e)
        {
            JSFCorePlugin.log("Error finding component type", e); //$NON-NLS-1$
        }

        return properties;
    }

    /**
     * @param project
     * @return a new proxy factory registry or null;
     * 
     * TODO: caching?
     */
    private static ProxyFactoryRegistry getProxyFactoryRegistry(
            final IProject project, final IConfigurationContributor[] contributors)
    {
        try
        {
            return IDERegistration.startAnImplementation(contributors, false, project,
                    project.getName(), JSFCorePlugin.PLUGIN_ID,
                    new NullProgressMonitor());
        }
        catch (final CoreException e)
        {
            JSFCorePlugin.log("Error starting vm for project: " //$NON-NLS-1$
                    + project.getName(), e);
        }

        return null;
    }

    private DTComponentIntrospector()
    {
        // no external instantiation
    }

    // private static class
}
