/*******************************************************************************
 * Copyright (c) 2006 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/Oracle - initial API and implementation
 *
 ********************************************************************************/
package org.eclipse.jst.jsf.core.internal.contentassist.el;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.IMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.provider.IContentProposalProvider;
import org.eclipse.jst.jsf.context.symbol.provider.ProposalCreationFactoryAdapter;
import org.eclipse.jst.jsf.context.symbol.provider.IContentProposalProvider.IProposalCreationFactory;
import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver;
import org.eclipse.jst.jsf.designtime.resolver.StructuredDocumentSymbolResolverFactory;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.swt.graphics.Image;

/**
 * A completion strategy for function completions like:
 *
 * v a r .
 *        ^
 *
 * @author cbateman
 *
 */
public class FunctionCompletionStrategy extends ContentAssistStrategy
{
    /**
     * @param value
     * @param proposalStart
     */
    public FunctionCompletionStrategy(final String value, final String proposalStart)
    {
        super(ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION, value, proposalStart);
    }

    @Override
	public List<ICompletionProposal> getProposals(final IStructuredDocumentContext context)
    {
        List<ICompletionProposal> completionList = Collections.EMPTY_LIST;
        final ISymbolContextResolver  symbolResolver =
            StructuredDocumentSymbolResolverFactory.getInstance().
                getSymbolContextResolver(context);

        final ISymbol symbol = SymbolResolveUtil.getSymbolForVariableSuffixExpr(context, getValue(), false);

        // if we get a completion symbol, get it's proposals
        if (symbol instanceof IObjectSymbol)
        {
            final List expectedMethodBindings = new ArrayList();
            final ISymbol[] suffixes = getSymbols((IObjectSymbol) symbol,
                                             context,
                                             symbolResolver,
                                             expectedMethodBindings);

            final ComposedAdapterFactory factory =
                new ComposedAdapterFactory(
                       ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
            final IProposalCreationFactory  creationInfo =
                new MyProposalFactory(context, getProposalStart().length(),
                                        expectedMethodBindings);
            
            completionList = new ArrayList<ICompletionProposal>();
            for (final ISymbol propSymbol : suffixes) {
                final Object  provider =
                  factory.adapt(propSymbol, IContentProposalProvider.class);

                if (provider instanceof IContentProposalProvider)
                {
                    final ICompletionProposal[] proposal  =
                        ((IContentProposalProvider) provider).
                            getProposals(propSymbol, creationInfo);
                    if (proposal != null)
                    {
                    	addProposalsMatchingProposalStart(completionList,
								proposal);
                    }
                }
            }
        }

        return Collections.unmodifiableList(completionList);
    }

	private ISymbol[] getSymbols(final IObjectSymbol symbol,
                                 final IStructuredDocumentContext context,
                                 final ISymbolContextResolver  symbolResolver,
                                 final List   expectedMethodBindings)
    {
        final List symbols = new ArrayList();

        if (SymbolResolveUtil.isMethodBindingExpected(context, expectedMethodBindings))
        {
            symbols.addAll(Arrays.asList(
                          symbolResolver.getMethods(symbol)));
        }

        symbols.addAll(Arrays.asList(symbolResolver.getProperties(symbol)));

        return (ISymbol[]) symbols.toArray(ISymbol.EMPTY_SYMBOL_ARRAY);
    }

    private static class MyProposalFactory extends ProposalCreationFactoryAdapter
    {
        private final static int   DEFAULT_RELEVANCE = 1;

        private final static int   HIGH_RELEVANCE = 2;
        private final static int   NORMAL_RELEVANCE = 1;
        private final static int   LOW_RELEVANCE = 0;

        private final List                         _expectedMethodBindings;
        private final IStructuredDocumentContext   _context;

        /**
         * @param context
         * @param replacementLength
         * @param expectedMethodBindings
         */
        public MyProposalFactory(final IStructuredDocumentContext context, final int replacementLength,
                                    final List expectedMethodBindings) {
            super(context.getDocumentPosition() - replacementLength, replacementLength);
            _context = context;
            _expectedMethodBindings = expectedMethodBindings;
        }

        @Override
		public ICompletionProposal createProposal(final String replacementText,
                                                  final String displayText,
                                                  final String additionalText,
                                                  final Image displayImage,
                                                  final Object target)
        {
            int replacementOffset = _replacementOffset;
            int replacementLength = _replacementLength;

            // TODO: I regard this as a bit of hack, but until we write our
            // proposal implementation, it's basically the only way I can
            // see to do this
            // if it's an array, we must check if we need to replace a
            // preceding '.'
            if (replacementText.startsWith("["))
            {
                ITextRegionContextResolver textResolver =
                    IStructuredDocumentContextResolverFactory.INSTANCE.getTextRegionResolver(_context);

                if (textResolver.getRegionType().equals(DOMJSPRegionContexts.JSP_VBL_CLOSE))
                {
                    textResolver =
                        IStructuredDocumentContextResolverFactory.
                            INSTANCE.getTextRegionResolver(textResolver.getPreviousContext());
                }

                final String regionText = textResolver.getRegionText();
                final int regionStart = textResolver.getStartOffset();

                if (DOMJSPRegionContexts.JSP_VBL_CONTENT.equals(textResolver.getRegionType())
                        && regionText != null
                        && regionStart != -1
                        && regionStart < _context.getDocumentPosition())
                {
                    final int  relativeOffset = _context.getDocumentPosition() - regionStart - 1;

                    if (regionText.charAt(relativeOffset) == '.')
                    {
                        // we must replace a length of 1 (the dot)
                        // at an offset on prior
                        replacementOffset--;
                        replacementLength = 1;
                    }
                }
            }

            return createDefaultProposal(replacementText,
                                         replacementOffset,
                                         replacementLength,
                                         replacementText.length(),
                                         displayImage,
                                         displayText,
                                         null,
                                         additionalText,
                                         getRelevance(target, DEFAULT_RELEVANCE));
        }

        private int getRelevance(final Object target, final int defaultRelevance)
        {
            // if method bindings are expected, then list exact signature
            // matches top most.  Still list non-matching methods, but put
            // them at the bottom
            if (_expectedMethodBindings.size() > 0)
            {
                if (target instanceof IMethodSymbol)
                {
                    final IMethodSymbol methodSymbol = (IMethodSymbol) target;

                    for (final Iterator it = _expectedMethodBindings.iterator();
                            it.hasNext();)
                    {
                        final String methodType = (String) it.next();

                        // we have a match, so push to the top
                        if (methodType.equals(methodSymbol.getSignature()))
                        {
                            return HIGH_RELEVANCE;
                        }
                    }

                    // if we get out of the loop, then this method doesn't
                    // match the expected signature
                    return LOW_RELEVANCE;
                }

                // non-method targets have normal relevance when mb expected
                return NORMAL_RELEVANCE;
            }

            // otherwise, simply return the default for all
            return defaultRelevance;
        }
    }
}
