/*******************************************************************************
 * Copyright (c) 2001, 2021 Oracle Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Oracle Corporation  - initial API and implementation
 *     Reto Weiss/Axon Ivy - Use cached JDTBeanIntrospector 
 *******************************************************************************/
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)
            {
                final JDTBeanIntrospector introspector = JDTBeanIntrospector.forType(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
}
