/*******************************************************************************
 * 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.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.internal.IJSFAppConfigManager;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.JSFAppConfigManagerFactory;
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 IJSFAppConfigManager manager = JSFAppConfigManagerFactory
                .getJSFAppConfigManagerInstance(project);
        final List<ComponentType> components = manager.getComponents();

        for (final ComponentType component : components)
        {
            final String type = component.getComponentType().getTextContent()
                    .trim();

            if (componentType.equals(type) && component.getComponentClass() != null && component.getComponentClass().getTextContent() != null)
            {
                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 IJSFAppConfigManager manager = JSFAppConfigManagerFactory
                .getJSFAppConfigManagerInstance(project);
        final List<ConverterType> converters = manager.getConverters();

        for (final ConverterType converter : converters)
        {
            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 IJSFAppConfigManager manager = JSFAppConfigManagerFactory
                .getJSFAppConfigManagerInstance(project);
        final List<ValidatorType> validators = manager.getValidators();

        for (final ValidatorType validatorType : validators)
        {
            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 (checkInstanceOf == null)
        {
            throw new AssertionError();
        }
        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
}
