/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) 
 *                                                                            
 *  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:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 *
 */
 
package org.eclipse.osbp.xtext.messagedsl.ui.contentassist

import com.google.inject.Inject
import java.util.TreeMap
import org.eclipse.emf.ecore.EObject
import org.eclipse.jface.viewers.StyledString
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper
import org.eclipse.osbp.xtext.messagedsl.MessageItem
import org.eclipse.osbp.xtext.messagedsl.ui.MessageDslUiDocumentationTranslator
import org.eclipse.swt.graphics.Image
import org.eclipse.xtext.Assignment
import org.eclipse.xtext.Keyword
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder

/**
 * see https://eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist on how to customize content assistant
 */
class MessageDslProposalProvider extends AbstractMessageDslProposalProvider {

    @Inject TerminalsProposalProvider provider
	@Inject BasicDSLProposalProviderHelper providerHelper

    /**
     * @see BasicDSLProposalProviderHelper#getKeywordDisplayString(Keyword, BasicDSLUiTranslator)
     * @param keyword the keyword to get the displayed string for
     * @return the displayed string
     */
    override protected StyledString getKeywordDisplayString(Keyword keyword) {
        return BasicDSLProposalProviderHelper.getKeywordDisplayString(keyword, MessageDslUiDocumentationTranslator.instance())
    }
    
    /**
     * This override will enable 1 length non letter characters as keyword.
     */
    override protected boolean isKeywordWorthyToPropose(Keyword keyword) {
        true
    }
    
    /**
     * convenience API to build and initialize JVM types and their members.
     */
    @Inject extension JvmTypesBuilder
    
 
 	override public void complete_QualifiedName(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this)
	}

    /**
     * see also {@link org.eclipse.osbp.xtext.messagedsl.common.Message.prepareMessage()}
     */
    override void completeMessageText_Text(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        // call implementation of superclass
        super.completeMessageText_Text(model, assignment, context, acceptor);
        // get all parameters given so far
        // generate all available variables depending on type of the parameter
        // check if the variable already inside the text
        val available = new TreeMap<String,String>
        val used = new TreeMap<String,String>
        val image = null as Image;
        val document = context.viewer.document.get.replace("\\\"", "''")
        val formatoffset = context.replaceRegion.offset
        val nextquote = document.indexOf('"', formatoffset+1)
        val replaceRegion = document.substring(formatoffset, nextquote+1)
        (model as MessageItem).parameters.forEach [ parameter |
            switch (parameter.oftype) {
                case BOOLEAN: {
                    val proposal = '''%%«parameter.name»%%'''
                    val displayString = '''«proposal» (boolean) «parameter.documentation»'''
                    if  (replaceRegion.contains(proposal)) {
                        used.put(proposal, '''used: «displayString»''')
                    }
                    else {
                        available.put(proposal, displayString)
                    }
                }
                case INTEGER: {
                    val proposal = '''%%«parameter.name»%%'''
                    val displayString = '''«proposal» (int) «parameter.documentation»'''
                    if  (replaceRegion.contains(proposal)) {
                        used.put(proposal, '''used: «displayString»''')
                    }
                    else {
                        available.put(proposal, displayString)
                    }
                }
                case DOUBLE: {
                    val proposal = '''%%«parameter.name»%%'''
                    val displayString = '''«proposal» (double) «parameter.documentation»'''
                    if  (replaceRegion.contains(proposal)) {
                        used.put(proposal, '''used: «displayString»''')
                    }
                    else {
                        available.put(proposal, displayString)
                    }
                }
                case STRING: {
                    val proposal = '''%%«parameter.name»%%'''
                    val displayString = '''«proposal» (String) «parameter.documentation»'''
                    if  (replaceRegion.contains(proposal)) {
                        used.put(proposal, '''used: «displayString»''')
                    }
                    else {
                        available.put(proposal, displayString)
                    }
                }
                case CLASS: {
                    {
                        val proposal = '''%%«parameter.name».canonicalName%%'''
                        val displayString = '''«proposal» (canonical name for Class) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».simpleName%%'''
                        val displayString = '''«proposal» (simple name for Class) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                }
                case OBJECT: {
                    {
                        val proposal = '''%%«parameter.name».canonicalName%%'''
                        val displayString = '''«proposal» (canonical name for Object) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».simpleName%%'''
                        val displayString = '''«proposal» (simple name for Object) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                }
                case EXCEPTION: {
                    {
                        val proposal = '''%%«parameter.name».canonicalName%%'''
                        val displayString = '''«proposal» (canonical name for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».simpleName%%'''
                        val displayString = '''«proposal» (simple name for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».localizedMessage%%'''
                        val displayString = '''«proposal» (localized message for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».localizedDetailMessage%%'''
                        val displayString = '''«proposal» (localized detail message for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».localizedSimpleDetailMessage%%'''
                        val displayString = '''«proposal» (localized simple detail message for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                    {
                        val proposal = '''%%«parameter.name».stackTrace%%'''
                        val displayString = '''«proposal» (stack trace for Exception) «parameter.documentation»'''
                        if  (replaceRegion.contains(proposal)) {
                            used.put(proposal, '''used: «displayString»''')
                        }
                        else {
                            available.put(proposal, displayString)
                        }
                    }
                }
            }
        ]
        // Create and register the completion proposal:
        // The proposal may be null as the createCompletionProposal(..) 
        // methods check for valid prefixes and terminal token conflicts.
        // The acceptor handles null-values gracefully.
        /* */
        available.forEach[ proposal, displayString |
            acceptor.accept(doCreateInStringProposal(proposal, new StyledString(displayString), image,
                getPriorityHelper().getDefaultPriority(), context));
        ]
        used.forEach[ proposal, displayString |
            acceptor.accept(doCreateInStringProposal(proposal, new StyledString(displayString), image,
                getPriorityHelper().getDefaultPriority(), context));
        ]
    }
    
    def private ConfigurableCompletionProposal doCreateInStringProposal(String proposal, StyledString displayString, Image image,
            int priority, ContentAssistContext context) {
        val selectedRange = context.viewer.getSelectedRange()
        val replacementOffset = selectedRange.x; // context.getReplaceRegion().getOffset();
        val replacementLength = selectedRange.y; // context.getReplaceRegion().getLength();
        val result = //doCreateProposal(proposal, displayString, image, replacementOffset, replacementLength);
            new InsideStringConfigurableCompletionProposal(proposal, replacementOffset, replacementLength, proposal.length(),
                image, displayString, null, null);
        result.setPriority(priority);
        result.setMatcher(context.getMatcher());
        result.setReplaceContextLength(context.getReplaceContextLength());
        return result;
    }
    
    	// ------------------------ delegates to TerminalsProposalProvider -----------------
	override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_ID(model, ruleCall, context, acceptor)
	}
    
}
