/**
 *                                                                            
 * 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 v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 *
 */
 
package org.eclipse.osbp.xtext.entitymock.ui.contentassist

import com.google.inject.Inject
import org.eclipse.emf.ecore.EObject
import org.eclipse.jface.viewers.StyledString
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute
import org.eclipse.osbp.ui.api.datamart.IDataMart
import org.eclipse.osbp.utils.entityhelper.DataType
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper
import org.eclipse.osbp.xtext.entitymock.EntityMockAttributeByObject
import org.eclipse.osbp.xtext.entitymock.EntityMockAttributeFiller
import org.eclipse.osbp.xtext.entitymock.EntityMockEntity
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectArrayValue
import org.eclipse.osbp.xtext.entitymock.EntityMockObjectEmbed
import org.eclipse.osbp.xtext.entitymock.EntityMockReferencedObjectAttribute
import org.eclipse.osbp.xtext.entitymock.EntityMockResource
import org.eclipse.osbp.xtext.entitymock.PropertyFillerDateFuture
import org.eclipse.osbp.xtext.entitymock.PropertyFillerDatePast
import org.eclipse.osbp.xtext.entitymock.PropertyFillerDateRange
import org.eclipse.osbp.xtext.entitymock.PropertyFillerSignedDoubleRandom
import org.eclipse.osbp.xtext.entitymock.PropertyFillerSignedDoubleRange
import org.eclipse.osbp.xtext.entitymock.PropertyFillerSignedIntegerRandom
import org.eclipse.osbp.xtext.entitymock.PropertyFillerSignedIntegerRange
import org.eclipse.osbp.xtext.entitymock.PropertyFillerTextParagraphs
import org.eclipse.osbp.xtext.entitymock.PropertyFillerTextRandom
import org.eclipse.osbp.xtext.entitymock.PropertyFillerTextSentences
import org.eclipse.osbp.xtext.entitymock.PropertyFillerTextWords
import org.eclipse.osbp.xtext.entitymock.PropertyFillerUnsignedDoubleRandom
import org.eclipse.osbp.xtext.entitymock.PropertyFillerUnsignedDoubleRange
import org.eclipse.osbp.xtext.entitymock.PropertyFillerUnsignedIntegerRandom
import org.eclipse.osbp.xtext.entitymock.PropertyFillerUnsignedIntegerRange
import org.eclipse.osbp.xtext.entitymock.ui.EntityMockDSLUiDocumentationTranslator
import org.eclipse.xtext.Assignment
import org.eclipse.xtext.Keyword
import org.eclipse.xtext.ParserRule
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor

/**
 * see http://www.eclipse.org/Xtext/documentation.html#contentAssist on how to customize content assistant
 */
class EntityMockDSLProposalProvider extends AbstractEntityMockDSLProposalProvider {
	
	@Inject DataType dtType
	@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, EntityMockDSLUiDocumentationTranslator.instance())
    }
    
    /**
     * This override will enable 1 length non letter characters as keyword.
     */
    override protected boolean isKeywordWorthyToPropose(Keyword keyword) {
        true
    }
    
    /**
     * propose all available enumeration values for the referenced enumeration
     */
    override public void completeEntityMockObjectItemValue_Datarow(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        var mockValueItem = model
        while (!(mockValueItem instanceof EntityMockObjectArrayValue) && (mockValueItem != null)) {
            mockValueItem = mockValueItem.eContainer
        }
        if  (mockValueItem instanceof EntityMockObjectArrayValue) {
        	if 	(mockValueItem.enumeration.usingResource instanceof EntityMockResource) {
    			val resource = mockValueItem.enumeration.usingResource as EntityMockResource
        		for (datarow : resource.datarows) {
            		acceptor.accept(
                		createCompletionProposal(datarow.name, datarow.name, null, context)
            		)
    			}
			}
			else {
    			val lenum = mockValueItem.enumeration.usingResource
        		for (datarow : lenum.literals) {
            		acceptor.accept(

	            		createCompletionProposal(datarow.name, datarow.name, null, context)
            		)
        		}
            }
        }
    }

    /**
     * propose all template mock object variables defined previously in this mock entity
     */
    override public void completeEntityMockReferencedObjectAttribute_Template(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        for (template : ((model as EntityMockAttributeByObject).eContainer as EntityMockEntity).templates) {
            acceptor.accept(
                createCompletionProposal(template.name, template.name, null, context)
            )
        }
    }

    /**
     * propose all embedded mock objects inside the referenced template mock object
     */    
    override public void completeEntityMockReferencedObjectAttribute_Embedded(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        var emroa = null as EntityMockReferencedObjectAttribute
        if  (model instanceof EntityMockReferencedObjectAttribute) {
            emroa = model
        }
        if  (model instanceof EntityMockAttributeByObject) {
            emroa = model.reference
        }
        var mockObject = emroa.template.object
        if  (!emroa.embedded.isEmpty) {
            mockObject = emroa.embedded.last.object
        }
        for (attribute : mockObject.attributes) {
            if  (attribute instanceof EntityMockObjectEmbed) {
                acceptor.accept(
                    createCompletionProposal(attribute.name, attribute.name, null, context)
                )
            }
        }
    }
    
    override public void completeEntityMockEntityFunction_AttributeRef(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
    	if	(model.eContainer instanceof EntityMockEntity) {
    		for	(attribute : (model.eContainer as EntityMockEntity).entityRef.allAttributes) {
                acceptor.accept(
                    createCompletionProposal(attribute.name, attribute.name, null, context)
                )
    		}
    	}
    	else {
	        super.completeEntityMockEntityFunction_AttributeRef(model, assignment, context, acceptor)
    	}
	}
    
    
    /**
     * propose all enumerations and attributes of the referenced (may be embedded) mock object
     */    
    override public void completeEntityMockReferencedObjectAttribute_Attribute(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
        var emroa = null as EntityMockReferencedObjectAttribute
        if  (model instanceof EntityMockReferencedObjectAttribute) {
            emroa = model
        }
        if  (model instanceof EntityMockAttributeByObject) {
            emroa = model.reference
        }
        var mockObject = emroa.template.object
        if  (!emroa.embedded.isEmpty) {
            mockObject = emroa.embedded.last.object
        }
        for (enumeration : mockObject.enumerations) {
            acceptor.accept(
                createCompletionProposal(enumeration.name, enumeration.name, null, context)
            )
        }
        for (attribute : mockObject.attributes) {
            if  (!(attribute instanceof EntityMockObjectEmbed)) {
                acceptor.accept(
                    createCompletionProposal(attribute.name, attribute.name, null, context)
                )
            }
        }
        for (calculation : mockObject.calculations) {
            acceptor.accept(
                createCompletionProposal(calculation.name, calculation.name, null, context)
            )
        }
    }
    
    /**
     * get the parser rule name for the given EObject
     */
    def protected String getParserRuleName(EObject object) {
        var retcode = null as String
        var parserRule = object
        while ((parserRule != null) && !(parserRule instanceof ParserRule)) {
            parserRule = parserRule.eContainer
        }
        if  (parserRule instanceof ParserRule) {
            retcode = parserRule.name
        }
        return retcode
    }

    /**
     * checks if the keywords parser rule is contained in the given Class
     */
    def protected boolean isKeywordInsideParserRule(Keyword keyword, Class<?> eClass) {
        var className = eClass.getCanonicalName
        return className.endsWith(keyword.parserRuleName)
    }

    /**
     * returns the allowed data type for the given Keyword
     */    
    def protected IDataMart.EType getPropertyFillerType(Keyword keyword) {
        if  (keyword.isKeywordInsideParserRule(PropertyFillerDateFuture)) return IDataMart.EType.DATE
        if  (keyword.isKeywordInsideParserRule(PropertyFillerDatePast)) return IDataMart.EType.DATE
        if  (keyword.isKeywordInsideParserRule(PropertyFillerDateRange)) return IDataMart.EType.DATE
        
        if  (keyword.isKeywordInsideParserRule(PropertyFillerSignedDoubleRandom)) return IDataMart.EType.DOUBLE
        if  (keyword.isKeywordInsideParserRule(PropertyFillerSignedDoubleRange)) return IDataMart.EType.DOUBLE
        if  (keyword.isKeywordInsideParserRule(PropertyFillerUnsignedDoubleRandom)) return IDataMart.EType.DOUBLE
        if  (keyword.isKeywordInsideParserRule(PropertyFillerUnsignedDoubleRange)) return IDataMart.EType.DOUBLE

        if  (keyword.isKeywordInsideParserRule(PropertyFillerSignedIntegerRandom)) return IDataMart.EType.INTEGER
        if  (keyword.isKeywordInsideParserRule(PropertyFillerSignedIntegerRange)) return IDataMart.EType.INTEGER
        if  (keyword.isKeywordInsideParserRule(PropertyFillerUnsignedIntegerRandom)) return IDataMart.EType.INTEGER
        if  (keyword.isKeywordInsideParserRule(PropertyFillerUnsignedIntegerRange)) return IDataMart.EType.INTEGER

        if  (keyword.isKeywordInsideParserRule(PropertyFillerTextParagraphs)) return IDataMart.EType.STRING
        if  (keyword.isKeywordInsideParserRule(PropertyFillerTextRandom)) return IDataMart.EType.STRING
        if  (keyword.isKeywordInsideParserRule(PropertyFillerTextSentences)) return IDataMart.EType.STRING
        if  (keyword.isKeywordInsideParserRule(PropertyFillerTextWords)) return IDataMart.EType.STRING
        
        return IDataMart.EType.NONE
    }

    /**
     * checks if the given Keyword is allowed for the given entity attribute type 
     */
    override protected boolean isKeywordWorthyToPropose(Keyword keyword, ContentAssistContext context) {
        if  (!super.isKeywordWorthyToPropose(keyword, context)) {
            return false
        }
        var currentModel = context.getCurrentModel();
        if  (currentModel instanceof EntityMockAttributeFiller) {
            var attributeByObject = currentModel as EntityMockAttributeFiller
            var LEntityAttribute attributeRef = attributeByObject.attributeRef as LEntityAttribute
            return dtType.canBeCastFrom(attributeRef, keyword.propertyFillerType)
        }
        return true
    }
        
    override protected boolean isValidProposal(String proposal, String prefix, ContentAssistContext context) {
        if  (!super.isValidProposal(proposal, prefix, context)) {
            return false
        }
        else {
            var currentModel = context.getCurrentModel();
            switch (currentModel) {
                EntityMockObjectArrayValue:    {
                    return true;
                }
                default:
                    return true //super.isValidProposal(proposal, prefix, context)
            }
        }
    }
    
    
    // ------------------------ delegates to TerminalsProposalProvider -----------------
	override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_ID(model, ruleCall, context, acceptor)
	}
    
	override public void complete_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, ruleCall, context, acceptor)
	}
    
	override public void complete_INT(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_INT(model, ruleCall, context, acceptor)
	}
	
	override public void complete_SINT(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_INT(model, ruleCall, context, acceptor)
	}
	
    // ------------------------ delegates to BasicDSLProposalProviderHelper providerHelper -----------------
	override public void complete_QualifiedName(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this)
	}

	override public void complete_UnsignedNumber(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		providerHelper.createNumberProposal(context, acceptor, ruleCall, this)
	}

	
    
}
