/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.common.xtext.ui.contentassist;

import java.lang.reflect.Field;
import java.sql.Blob;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.osbp.dsl.semantic.common.helper.Bounds;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.runtime.common.layouting.IPropertyConstants;
import org.eclipse.osbp.runtime.common.layouting.IPropertyConstants.DSLModelsEnum;
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper;
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 com.google.inject.Inject;

/**
 * see http://www.eclipse.org/Xtext/documentation.html#contentAssist on how to
 * customize content assistant
 */
public class CommonGrammarProposalProvider extends org.eclipse.osbp.dsl.common.xtext.ui.contentassist.AbstractCommonGrammarProposalProvider {

	@Inject
	TerminalsProposalProvider provider;
	@Inject
	BasicDSLProposalProviderHelper providerHelper;

	private static final String IS_PAST = "isPast";
	private static final String IS_FUTURE = "isFuture";
	private static final String MAX_SIZE = "maxSize";
	private static final String MIN_SIZE = "minSize";
	private static final String REGEX = "regex";
	private static final String IS_TRUE = "isTrue";
	private static final String IS_FALSE = "isFalse";
	private static final String IS_NULL = "isNull";
	private static final String IS_NOT_NULL = "isNotNull";
	private static final String MIN_NUMBER = "minNumber";
	private static final String MAX_NUMBER = "maxNumber";
	private static final String DIGITS = "digits";
	private static final String MIN_DECIMAL = "minDecimal";
	private static final String MAX_DECIMAL = "maxDecimal";
	private static Set<String> constraints = new HashSet<String>();
	private static Map<String, Set<String>> allowedConstraints = new HashMap<String, Set<String>>();
	static {
		constraints.add(IS_FALSE);
		constraints.add(IS_TRUE);
		constraints.add(MAX_DECIMAL);
		constraints.add(MIN_DECIMAL);
		constraints.add(DIGITS);
		constraints.add(IS_FUTURE);
		constraints.add(IS_PAST);
		constraints.add(MAX_NUMBER);
		constraints.add(MIN_NUMBER);
		constraints.add(IS_NOT_NULL);
		constraints.add(IS_NULL);
		constraints.add(REGEX);
		constraints.add(MIN_SIZE);
		constraints.add(MAX_SIZE);

		// constraints for String
		Set<String> stringConstraints = new HashSet<String>();
		allowedConstraints.put(String.class.getCanonicalName(), stringConstraints);
		stringConstraints.add(IS_NOT_NULL);
		stringConstraints.add(IS_NULL);
		stringConstraints.add(REGEX);
		stringConstraints.add(MIN_SIZE);
		stringConstraints.add(MAX_SIZE);

		// constraints for String
		Set<String> charConstraints = new HashSet<String>();
		allowedConstraints.put(Character.class.getCanonicalName(), stringConstraints);
		charConstraints.add(IS_NOT_NULL);
		charConstraints.add(IS_NULL);
		charConstraints.add(REGEX);

		// constraints for numeric
		Set<String> numericConstraints = new HashSet<String>();
		allowedConstraints.put(Short.class.getCanonicalName(), numericConstraints);
		allowedConstraints.put(Byte.class.getCanonicalName(), numericConstraints);
		allowedConstraints.put(Integer.class.getCanonicalName(), numericConstraints);
		allowedConstraints.put(Long.class.getCanonicalName(), numericConstraints);
		numericConstraints.add(MAX_NUMBER);
		numericConstraints.add(MIN_NUMBER);
		numericConstraints.add(IS_NOT_NULL);
		numericConstraints.add(IS_NULL);

		// constraints for decimal
		Set<String> decimalConstraints = new HashSet<String>();
		allowedConstraints.put(Float.class.getCanonicalName(), decimalConstraints);
		allowedConstraints.put(Double.class.getCanonicalName(), decimalConstraints);
		decimalConstraints.add(MAX_DECIMAL);
		decimalConstraints.add(MIN_DECIMAL);
		decimalConstraints.add(DIGITS);
		decimalConstraints.add(IS_NOT_NULL);
		decimalConstraints.add(IS_NULL);

		// constraints for boolean
		Set<String> booleanConstraints = new HashSet<String>();
		allowedConstraints.put(Boolean.class.getCanonicalName(), booleanConstraints);
		booleanConstraints.add(IS_FALSE);
		booleanConstraints.add(IS_TRUE);
		booleanConstraints.add(IS_NOT_NULL);
		booleanConstraints.add(IS_NULL);

		// constraints for Date
		Set<String> dateConstraints = new HashSet<String>();
		allowedConstraints.put(Date.class.getCanonicalName(), dateConstraints);
		dateConstraints.add(IS_NOT_NULL);
		dateConstraints.add(IS_NULL);
		dateConstraints.add(IS_PAST);
		dateConstraints.add(IS_FUTURE);

		// constraints for Blob
		Set<String> blobConstraints = new HashSet<String>();
		allowedConstraints.put(Blob.class.getCanonicalName(), blobConstraints);
		blobConstraints.add(IS_NOT_NULL);
		blobConstraints.add(IS_NULL);
	}

	@Override
	public void complete_DtCDecimalMax(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (!context.getPrefix().equals("minDecimal")) {
			return;
		}
		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("minDecimal(-123.456)", new StyledString("minDecimal(-123.456)"), null,
				replacementOffset, replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);

	}

	@Override
	public void complete_DtCDecimalMin(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (!context.getPrefix().equals("maxDecimal")) {
			return;
		}

		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("maxDecimal(123.456)", new StyledString("maxDecimal(123.456)"), null,
				replacementOffset, replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);
	}

	@Override
	public void complete_DtCDigits(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (!context.getPrefix().equals("digits")) {
			return;
		}

		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("digits(7, 3)", new StyledString("digits(7, 3)"), null, replacementOffset,
				replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);
	}

	@Override
	public void complete_DtCNumericMax(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (!context.getPrefix().equals("maxNumber")) {
			return;
		}

		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("maxNumber(7)", new StyledString("maxNumber(7)"), null, replacementOffset,
				replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);
	}

	@Override
	public void complete_DtCNumericMin(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (!context.getPrefix().equals("minNumber")) {
			return;
		}

		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("minNumber(-7)", new StyledString("minNumber(-7)"), null,
				replacementOffset, replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);
	}

	@Override
	public void complete_DtCRegEx(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		if (!context.getPrefix().equals("regex")) {
			return;
		}

		int replacementOffset = context.getReplaceRegion().getOffset();
		int replacementLength = context.getReplaceRegion().getLength() + 1;

		ConfigurableCompletionProposal result = doCreateProposal("regex(\"A[0-9]*\")", new StyledString("regex(\"A[0-9]*\")"), null,
				replacementOffset, replacementLength);
		result.setPriority(1000);
		result.setMatcher(context.getMatcher());
		result.setReplaceContextLength(context.getReplaceContextLength());
		acceptor.accept(result);
	}

	@Override
	public void complete_DtCSize(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {

		if (context.getPrefix().equals("minSize")) {
			int replacementOffset = context.getReplaceRegion().getOffset();
			int replacementLength = context.getReplaceRegion().getLength() + 1;

			ConfigurableCompletionProposal result = doCreateProposal("minSize(0)", new StyledString("minSize(0)"), null, replacementOffset,
					replacementLength);
			result.setPriority(1000);
			result.setMatcher(context.getMatcher());
			result.setReplaceContextLength(context.getReplaceContextLength());
			acceptor.accept(result);
		} else if (context.getPrefix().equals("maxSize")) {
			int replacementOffset = context.getReplaceRegion().getOffset();
			int replacementLength = context.getReplaceRegion().getLength() + 1;

			ConfigurableCompletionProposal result = doCreateProposal("maxSize(10)", new StyledString("maxSize(10)"), null,
					replacementOffset, replacementLength);
			result.setPriority(1000);
			result.setMatcher(context.getMatcher());
			result.setReplaceContextLength(context.getReplaceContextLength());
			acceptor.accept(result);
		}
	}

	protected boolean isKeywordWorthyToPropose(Keyword keyword, ContentAssistContext context) {
		EObject model = context.getCurrentModel();
		if (model instanceof LDataType) {
			String value = keyword.getValue();
			if (constraints.contains(value)) {
				LDataType dt = (LDataType) model;
				return forDatatype(value, dt);
			}
		} else if (model instanceof LAttribute) {
			String value = keyword.getValue();
			if (constraints.contains(value)) {
				LAttribute att = (LAttribute) model;
				if (att.getType() instanceof LDataType) {
					LDataType dt = (LDataType) att.getType();
					return forDatatype(value, dt);
				}
			}
		} else if (model instanceof LReference) {
			String value = keyword.getValue();
			if (constraints.contains(value)) {
				LReference ref = (LReference) model;
				if (Bounds.createFor(ref).isToMany()) {
					return false;
				}
				if (!value.equals(IS_NOT_NULL) && !value.equals(IS_NULL)) {
					return false;
				}
			}
		}
		return true;
	}

	protected boolean forDatatype(String value, LDataType dt) {
		if (!dt.isDate() && !dt.isAsBlob()) {
			if (dt.isAsPrimitive() && (value.equals(IS_NOT_NULL) || value.equals(IS_NULL))) {
				return false;
			}
			String fqn = dt.getJvmTypeReference().getQualifiedName();
			Set<String> constraints = allowedConstraints.get(fqn);
			if (constraints != null) {
				return constraints.contains(value);
			} else {
				return false;
			}
		} else if (dt.isDate()) {
			Set<String> constraints = allowedConstraints.get(Date.class.getCanonicalName());
			if (constraints != null) {
				return constraints.contains(value);
			} else {
				return false;
			}
		} else if (dt.isAsBlob()) {
			Set<String> constraints = allowedConstraints.get(Blob.class.getCanonicalName());
			if (constraints != null) {
				return constraints.contains(value);
			} else {
				return false;
			}
		}

		return false;
	}
	
	@Override
	public void completeKeyAndValue_Value(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		if (IPropertyConstants.PROPERTY_MODEL.equalsIgnoreCase(((LKeyAndValue)model).getKey())){
			for (DSLModelsEnum modelsEnum : DSLModelsEnum.values()) {
				ICompletionProposal proposal = createCompletionProposal("\"" + modelsEnum.name() + "\"", context);
				acceptor.accept(proposal);
			} 
		}
		super.completeKeyAndValue_Value(model, assignment, context, acceptor);
	}

	
	@Override
	public void completeKeyAndValue_Key(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		for (Field field : IPropertyConstants.class.getDeclaredFields()) {
			if (field.getName().startsWith("PROPERTY_")){
				try {
					Object result = field.get(null);
					ICompletionProposal proposal = createCompletionProposal("\"" + result + "\"", context);
					acceptor.accept(proposal);
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} 
		completeRuleCall(((RuleCall)assignment.getTerminal()), context, acceptor);
	}


	// ------------- delegates to TerminalsProposalProvider ------------------
	public void complete_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, ruleCall, context, acceptor);
	}

	public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_ID(model, ruleCall, context, acceptor);
	}

	public void complete_ValidIDWithKeywords(EObject model, RuleCall ruleCall, ContentAssistContext context,
			ICompletionProposalAcceptor acceptor) {
		provider.complete_ID(model, ruleCall, context, acceptor);
	}

	// ------------- delegates to BasicDSLProposalProviderHelper -------------
	public void complete_QualifiedName(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this);
	}

	public void complete_LQualifiedNameWithWildCard(EObject model, RuleCall ruleCall, ContentAssistContext context,
			ICompletionProposalAcceptor acceptor) {
		providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this);
	}

}
