/*******************************************************************************
 * Copyright (c) 2008 Oracle Corporation.
 * 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:
 *    Cameron Bateman - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facelet.core.internal.registry.taglib;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.internal.proxy.core.IBeanProxy;
import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
import org.eclipse.jem.internal.proxy.core.IBooleanBeanProxy;
import org.eclipse.jem.internal.proxy.core.IFieldProxy;
import org.eclipse.jem.internal.proxy.core.IMethodProxy;
import org.eclipse.jem.internal.proxy.core.IStringBeanProxy;
import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry;
import org.eclipse.jem.internal.proxy.core.ThrowableProxy;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil;
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.facelet.core.internal.FaceletCorePlugin;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.ComponentTagDefn;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.ConverterTagDefn;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.FaceletLibraryClassTagLib;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.FaceletTaglibFactory;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.TagDefn;
import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib.ValidatorTagDefn;

/**
 * @author cbateman
 * 
 */
/* package */class LibraryClassBasedTagRecord extends FaceletTagRecord
{
    private static final String             METHOD_NAME_GET_VALUE                                                     = "getValue";                                                           //$NON-NLS-1$
    private static final String             METHOD_NAME_GET_KEY                                                       = "getKey";                                                             //$NON-NLS-1$
    private static final String             METHOD_NAME_HAS_NEXT                                                      = "hasNext";                                                            //$NON-NLS-1$
    private static final String             METHOD_NAME_NEXT                                                          = "next";                                                               //$NON-NLS-1$
    private static final String             METHOD_NAME_ITERATOR                                                      = "iterator";                                                           //$NON-NLS-1$
    private static final String             METHOD_NAME_ENTRY_SET                                                     = "entrySet";                                                           //$NON-NLS-1$
    private static final String             PROPERTY_NAME_FACTORIES                                                   = "factories";                                                          //$NON-NLS-1$
    private static final String             QUALIFIED_CLASS_NAME__COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY           = "com.sun.facelets.tag.AbstractTagLibrary";                            //$NON-NLS-1$
    private static final String             QUALIFIED_CLASS_NAME_JAVA_UTIL_MAP                                        = "java.util.Map";                                                      //$NON-NLS-1$

    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY                = "com.sun.facelets.tag.AbstractTagLibrary$HandlerFactory";             //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_CONVERTER_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserConverterHandlerFactory"; //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_CONVERTER_HANDLER_FACTORY      = "com.sun.facelets.tag.AbstractTagLibrary$ConverterHandlerFactory";    //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_VALIDATOR_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserValidatorHandlerFactory"; //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_VALIDATOR_HANDLER_FACTORY      = "com.sun.facelets.tag.AbstractTagLibrary$ValidatorHandlerFactory";    //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_COMPONENT_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserComponentHandlerFactory"; //$NON-NLS-1$
    private static final String             COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_COMPONENT_HANDLER_FACTORY      = "com.sun.facelets.tag.AbstractTagLibrary$ComponentHandlerFactory";    //$NON-NLS-1$

    private static final String             FIELD_NAME_CONVERTER_ID                                                   = "converterId";                                                        //$NON-NLS-1$
    private static final String             FIELD_NAME_VALIDATOR_ID                                                   = "validatorId";                                                        //$NON-NLS-1$
    private static final String             FIELD_NAME_RENDER_TYPE                                                    = "renderType";                                                         //$NON-NLS-1$
    private static final String             FIELD_NAME_COMPONENT_TYPE                                                 = "componentType";                                                      //$NON-NLS-1$

    /**
     * 
     */
    private static final long               serialVersionUID                                                          = 4174629773250721041L;
    private static final String             STATIC_MEMBER_NAMESPACE                                                   = "Namespace";                                                          //$NON-NLS-1$
    private static final String             METHOD_NAME_GET_NAMESPACE                                                 = "getNamespace";                                                       //$NON-NLS-1$

    private final IProject _project;
    private final FaceletLibraryClassTagLib _model;
    private final ProxyFactoryRegistry      _registry;
    private final AtomicBoolean             _isInitialized                                                            = new AtomicBoolean(
                                                                                                                              false);

    private String                          _uri;
    private BeanProxyWrapper                _classTypeWrapper;
    private Map<String, TagDefn>            _tags;

    /**
     * @param registry
     * @param model
     * @param project 
     */
    public LibraryClassBasedTagRecord(final ProxyFactoryRegistry registry,
            final FaceletLibraryClassTagLib model, final IProject project)
    {
        _registry = registry;
        _model = model;
        _project = project;
    }

    public void initURI() throws CoreException
    {
        if (_isInitialized.get())
        {
            throw new CoreException(
                    new Status(
                            IStatus.ERROR,
                            JSFCorePlugin.PLUGIN_ID,
                            "Cannot initURI once the library is initialized for: " + _model.getLibraryClass())); //$NON-NLS-1$
        }

        final IBeanTypeProxy libFactoryTypeProxy = _registry
                .getBeanTypeProxyFactory().getBeanTypeProxy(
                        _model.getLibraryClass());

        if (libFactoryTypeProxy == null)
        {
            throw new CoreException(new Status(IStatus.ERROR,
                    JSFCorePlugin.PLUGIN_ID,
                    "Couldn't find type proxy for " + _model.getLibraryClass())); //$NON-NLS-1$
        }

        // TODO: wrap in try per the Glassfish patch
        _classTypeWrapper = new BeanProxyWrapper(_project, libFactoryTypeProxy);

        try
        {
            _classTypeWrapper.init();
        }
        catch (final ProxyException e)
        {
            throw new CoreException(new Status(IStatus.ERROR,
                    JSFCorePlugin.PLUGIN_ID,
                    "Couldn't load class: " + _model.getLibraryClass(), e)); //$NON-NLS-1$
        }

        final String namespace = resolveNS(_classTypeWrapper);
        System.out.println(namespace);

        if (namespace == null)
        {
            throw new CoreException(new Status(IStatus.ERROR,
                    JSFCorePlugin.PLUGIN_ID,
                    "Couldn't load uri: " + _model.getLibraryClass())); //$NON-NLS-1$

        }
        _uri = namespace;
    }

    @Override
    public synchronized TagDefn getTag(final String name)
    {
        initializeIfNecessary();
        return _tags.get(name);
    }

    @Override
    public synchronized Collection<? extends TagDefn> getTags()
    {
        initializeIfNecessary();
        return Collections.unmodifiableCollection(_tags.values());
    }

    private void initializeIfNecessary()
    {
        if (_isInitialized.compareAndSet(false, true))
        {
            if (_tags == null)
            {
                _tags = resolveTags();
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.FaceletTagRecord
     * #getURI()
     */
    @Override
    public String getURI()
    {
        return _uri;
    }

    private Map<String, TagDefn> resolveTags()
    {
        final Map<String, TagDefn> tags = new HashMap<String, TagDefn>();

        // if the tag factory is a child of AbstractTagFactory, then we
        // can try to get our hands on its private parts ...
        final IBeanTypeProxy mapTypeProxy = _registry.getBeanTypeProxyFactory()
                .getBeanTypeProxy(QUALIFIED_CLASS_NAME_JAVA_UTIL_MAP);
        final IBeanTypeProxy componentFactoryTypeProxy = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        QUALIFIED_CLASS_NAME__COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY);

        if (mapTypeProxy != null && componentFactoryTypeProxy != null)
        {
            final IFieldProxy fieldProxy = componentFactoryTypeProxy
                    .getDeclaredFieldProxy(PROPERTY_NAME_FACTORIES);

            if (fieldProxy != null)
            {
                if (fieldProxy.getFieldType().isKindOf(mapTypeProxy))
                {
                    IBeanProxy factories = null;

                    try
                    {
                        // need to turn off security checking on the private
                        // field
                        fieldProxy.setAccessible(true);
                        factories = fieldProxy.get(_classTypeWrapper
                                .getInstance());
                    }
                    catch (final ThrowableProxy e)
                    {
                        FaceletCorePlugin.log(
                                "Error getting factories from bean instance", //$NON-NLS-1$
                                e);
                    }

                    if (factories != null)
                    {
                        final IMethodProxy entrySetMethod = fieldProxy
                                .getFieldType().getMethodProxy(
                                        METHOD_NAME_ENTRY_SET);
                        if (entrySetMethod != null)
                        {
                            try
                            {
                                entrySetMethod.setAccessible(true);
                                final IBeanProxy entrySetProxy = entrySetMethod
                                        .invoke(factories);

                                if (entrySetProxy != null)
                                {
                                    final IMethodProxy iteratorMethod = entrySetProxy
                                            .getTypeProxy().getMethodProxy(
                                                    METHOD_NAME_ITERATOR);
                                    iteratorMethod.setAccessible(true);
                                    final IBeanProxy iteratorProxy = iteratorMethod
                                            .invoke(entrySetProxy);

                                    if (iteratorProxy != null)
                                    {
                                        final IMethodProxy nextMethod = iteratorProxy
                                                .getTypeProxy().getMethodProxy(
                                                        METHOD_NAME_NEXT);
                                        nextMethod.setAccessible(true);
                                        final IMethodProxy hasNextMethod = iteratorProxy
                                                .getTypeProxy().getMethodProxy(
                                                        METHOD_NAME_HAS_NEXT);
                                        hasNextMethod.setAccessible(true);

                                        while (((IBooleanBeanProxy) hasNextMethod
                                                .invoke(iteratorProxy))
                                                .booleanValue())
                                        {
                                            final IBeanProxy entryProxy = nextMethod
                                                    .invoke(iteratorProxy);
                                            final IMethodProxy getKeyProxy = entryProxy
                                                    .getTypeProxy()
                                                    .getMethodProxy(
                                                            METHOD_NAME_GET_KEY);
                                            final IMethodProxy getValueProxy = entryProxy
                                                    .getTypeProxy()
                                                    .getMethodProxy(
                                                            METHOD_NAME_GET_VALUE);
                                            if (getKeyProxy != null
                                                    && getValueProxy != null)
                                            {
                                                getKeyProxy.setAccessible(true);
                                                final IBeanProxy key = getKeyProxy
                                                        .invoke(entryProxy);

                                                if (key instanceof IStringBeanProxy)
                                                {
                                                    final String name = ((IStringBeanProxy) key)
                                                            .stringValue();
                                                    getValueProxy
                                                            .setAccessible(true);
                                                    final IBeanProxy value = getValueProxy
                                                            .invoke(entryProxy);

                                                    if (value != null)
                                                    {
                                                        final TagDefn tagDefn = createTagDefn(
                                                                name,
                                                                value);
                                                        if (tagDefn != null)
                                                        {
                                                            tags.put(name,
                                                                    tagDefn);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (final ThrowableProxy e)
                            {
                                FaceletCorePlugin.log(
                                        "Error invoking entrySet", e); //$NON-NLS-1$
                            }
                        }
                    }

                }
            }
        }
        return tags;
    }

    private TagDefn createTagDefn(final String name,
            final IBeanProxy handlerValueProxy)
    {
        final IBeanTypeProxy handlerTypeProxy = handlerValueProxy.getTypeProxy();
        final FaceletTaglibFactory TAGDEFN_FACTORY = FaceletTaglibFactory.eINSTANCE;

        final IBeanTypeProxy componentHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_COMPONENT_HANDLER_FACTORY);
        final IBeanTypeProxy userComponentHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_COMPONENT_HANDLER_FACTORY);
        final IBeanTypeProxy validatorHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_VALIDATOR_HANDLER_FACTORY);
        final IBeanTypeProxy userValidatorHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_VALIDATOR_HANDLER_FACTORY);
        final IBeanTypeProxy converterHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_CONVERTER_HANDLER_FACTORY);
        final IBeanTypeProxy userConverterHandlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_CONVERTER_HANDLER_FACTORY);
        final IBeanTypeProxy handlerFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY);
        final IBeanTypeProxy userTagFactory = _registry
                .getBeanTypeProxyFactory()
                .getBeanTypeProxy(
                        COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY);

        TagDefn tagDefn = null;

        if (handlerTypeProxy.isKindOf(componentHandlerFactory)
                || handlerTypeProxy.isKindOf(userComponentHandlerFactory))
        {
            final IFieldProxy componentTypeProxy = handlerTypeProxy
                    .getDeclaredFieldProxy(FIELD_NAME_COMPONENT_TYPE);
            final IFieldProxy rendererTypeProxy = handlerTypeProxy
                    .getDeclaredFieldProxy(FIELD_NAME_RENDER_TYPE);
            try
            {
                if (componentTypeProxy != null)
                {
                    componentTypeProxy.setAccessible(true);
                    rendererTypeProxy.setAccessible(true);
                    final IBeanProxy componentType = componentTypeProxy
                            .get(handlerValueProxy);
                    // final IBeanProxy rendererType = rendererTypeProxy
                    // .get(handlerValueProxy);

                    // render type is optional, but must have component type
                    if (componentType instanceof IStringBeanProxy)
                    {
                        final String componentTypeValue = getMeaningfulString(((IStringBeanProxy) componentType)
                                .stringValue());

                        if (componentTypeValue != null)
                        {
                            final ComponentTagDefn compTagDefn = TAGDEFN_FACTORY
                                    .createComponentTagDefn();
                            compTagDefn.setComponentType(componentTypeValue);
                            // if (rendererType instanceof IStringBeanProxy)
                            // {
                            // compTagDefn
                            // .setRendererType(getMeaningfulString(((
                            // IStringBeanProxy) rendererType)
                            // .stringValue()));
                            // }
                            tagDefn = compTagDefn;
                        }
                    }
                }
            }
            catch (final ThrowableProxy e)
            {
                FaceletCorePlugin.log("Error get component info", e); //$NON-NLS-1$
            }
        }
        else if (handlerTypeProxy.isKindOf(validatorHandlerFactory)
                || handlerTypeProxy.isKindOf(userValidatorHandlerFactory))
        {
            final IFieldProxy validatorIdProxy = handlerTypeProxy
                    .getDeclaredFieldProxy(FIELD_NAME_VALIDATOR_ID);

            try
            {
                if (validatorIdProxy != null)
                {
                    validatorIdProxy.setAccessible(true);
                    final IBeanProxy validatorId = validatorIdProxy
                            .get(handlerValueProxy);

                    final ValidatorTagDefn valTagDefn = TAGDEFN_FACTORY
                            .createValidatorTagDefn();
                    tagDefn = valTagDefn;

                    if (validatorId instanceof IStringBeanProxy)
                    {
                        final String validatorIdValue = getMeaningfulString(((IStringBeanProxy) validatorId)
                                .stringValue());

                        if (validatorIdValue != null)
                        {
                            valTagDefn.setValidatorId(validatorIdValue);
                        }
                    }
                }
            }
            catch (final ThrowableProxy e)
            {
                FaceletCorePlugin.log("Error getting validator info", e); //$NON-NLS-1$
            }
        }
        else if (handlerTypeProxy.isKindOf(converterHandlerFactory)
                || handlerTypeProxy.isKindOf(userConverterHandlerFactory))
        {
            final IFieldProxy converterIdProxy = handlerTypeProxy
                    .getDeclaredFieldProxy(FIELD_NAME_CONVERTER_ID);

            try
            {
                if (converterIdProxy != null)
                {
                    converterIdProxy.setAccessible(true);
                    final IBeanProxy converterId = converterIdProxy
                            .get(handlerValueProxy);

                    final ConverterTagDefn converterTagDefn = TAGDEFN_FACTORY
                            .createConverterTagDefn();
                    tagDefn = converterTagDefn;

                    if (converterId instanceof IStringBeanProxy)
                    {
                        final String converterIdValue = getMeaningfulString(((IStringBeanProxy) converterId)
                                .stringValue());

                        if (converterIdValue != null)
                        {
                            converterTagDefn.setConverterId(converterIdValue);
                        }
                    }
                }
            }
            catch (final ThrowableProxy e)
            {
                FaceletCorePlugin.log("Error getting validator info", e); //$NON-NLS-1$
            }
        }
        else if (handlerTypeProxy.isKindOf(handlerFactory)
                || handlerTypeProxy.isKindOf(userTagFactory))
        {
            tagDefn = TAGDEFN_FACTORY.createHandlerTagDefn();
        }

        if (tagDefn != null)
        {
            tagDefn.setName(name);
        }
        return tagDefn;
    }

    private String getMeaningfulString(final String value)
    {
        if (value == null)
        {
            return null;
        }

        String retValue = value.trim();

        if ("".equals(retValue)) //$NON-NLS-1$
        {
            retValue = null;
        }
        return retValue;
    }

    private String resolveNS(final BeanProxyWrapper beanProxy)
    {
        IBeanProxy resultProxy = null;
        try
        {
            resultProxy = beanProxy.call(METHOD_NAME_GET_NAMESPACE);

            if (resultProxy instanceof IStringBeanProxy)
            {
                return ((IStringBeanProxy) resultProxy).stringValue();
            }
        }
        catch (final BeanProxyUtil.ProxyException e)
        {
            // fall through
        }

        return resolveNSAggressively(beanProxy);
    }

    private String resolveNSAggressively(final BeanProxyWrapper beanProxy)
    {
        try
        {
            return beanProxy.getStringFieldValue(STATIC_MEMBER_NAMESPACE);
        }
        catch (final ProxyException e)
        {
            // fall through
        }
        return null;
    }

    public synchronized int getNumTags()
    {
        initializeIfNecessary();
        return _tags.size();
    }
}
