/**
 * Copyright (c) 2013, 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
 */
package org.eclipse.osbp.xtext.datamartdsl.ui.contentassist;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper;
import org.eclipse.osbp.xtext.cubedsl.CubeLevel;
import org.eclipse.osbp.xtext.cubedsl.CubeMeasure;
import org.eclipse.osbp.xtext.datamartdsl.AxisEnum;
import org.eclipse.osbp.xtext.datamartdsl.ConditionalExpression;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttributeBase;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAxis;
import org.eclipse.osbp.xtext.datamartdsl.DatamartCondition;
import org.eclipse.osbp.xtext.datamartdsl.DatamartCube;
import org.eclipse.osbp.xtext.datamartdsl.DatamartCubeAxis;
import org.eclipse.osbp.xtext.datamartdsl.DatamartCubeElement;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefineDerivedMeasure;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDerivedMeasure;
import org.eclipse.osbp.xtext.datamartdsl.DatamartElement;
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity;
import org.eclipse.osbp.xtext.datamartdsl.DatamartHierarchy;
import org.eclipse.osbp.xtext.datamartdsl.DatamartMeasure;
import org.eclipse.osbp.xtext.datamartdsl.DatamartOrder;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSlicer;
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask;
import org.eclipse.osbp.xtext.datamartdsl.Expression;
import org.eclipse.osbp.xtext.datamartdsl.OrderEnum;
import org.eclipse.osbp.xtext.datamartdsl.SetAggregationEnum;
import org.eclipse.osbp.xtext.datamartdsl.ui.DatamartDSLDocumentationTranslator;
import org.eclipse.osbp.xtext.datamartdsl.ui.contentassist.AbstractDatamartDSLProposalProvider;
import org.eclipse.osbp.xtext.datamartdsl.util.AxisEnumUtil;
import org.eclipse.osbp.xtext.datamartdsl.util.SetAggregationEnumUtil;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider;
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * see http://www.eclipse.org/Xtext/documentation.html#contentAssist on how to customize content assistant
 */
@SuppressWarnings("all")
public class DatamartDSLProposalProvider extends AbstractDatamartDSLProposalProvider {
  @Inject
  private TerminalsProposalProvider provider;
  
  @Inject
  private BasicDSLProposalProviderHelper providerHelper;
  
  @Override
  protected StyledString getKeywordDisplayString(final Keyword keyword) {
    return BasicDSLProposalProviderHelper.getKeywordDisplayString(keyword, 
      DatamartDSLDocumentationTranslator.instance());
  }
  
  /**
   * This override will enable 1 length non letter characters as keyword.
   */
  @Override
  protected boolean isKeywordWorthyToPropose(final Keyword keyword) {
    return true;
  }
  
  @Override
  protected boolean isValidProposal(final String proposal, final String prefix, final ContentAssistContext context) {
    boolean result = super.isValidProposal(proposal, prefix, context);
    EObject _currentModel = context.getCurrentModel();
    if ((_currentModel instanceof DatamartAxis)) {
      EObject _currentModel_1 = context.getCurrentModel();
      return this.isAxisValidProposal(((DatamartAxis) _currentModel_1), proposal, result);
    } else {
      EObject _currentModel_2 = context.getCurrentModel();
      if ((_currentModel_2 instanceof DatamartHierarchy)) {
        EObject _currentModel_3 = context.getCurrentModel();
        return this.isHierarchyValidProposal(((DatamartHierarchy) _currentModel_3), proposal, result);
      } else {
        EObject _currentModel_4 = context.getCurrentModel();
        if ((_currentModel_4 instanceof DatamartAttribute)) {
          EObject _currentModel_5 = context.getCurrentModel();
          return this.isAttributeValidProposal(((DatamartAttribute) _currentModel_5), proposal, result);
        } else {
          EObject _currentModel_6 = context.getCurrentModel();
          if ((_currentModel_6 instanceof DatamartCondition)) {
            EObject _currentModel_7 = context.getCurrentModel();
            return this.isConditionValidProposal(((DatamartCondition) _currentModel_7), proposal, result);
          } else {
            EObject _currentModel_8 = context.getCurrentModel();
            if ((_currentModel_8 instanceof ConditionalExpression)) {
              EObject _currentModel_9 = context.getCurrentModel();
              return this.isConditionalExpressionValidProposal(((ConditionalExpression) _currentModel_9), proposal, result);
            } else {
              EObject _currentModel_10 = context.getCurrentModel();
              if ((_currentModel_10 instanceof DatamartOrder)) {
                EObject _currentModel_11 = context.getCurrentModel();
                return this.isOrderValidProposal(((DatamartOrder) _currentModel_11), proposal, result);
              } else {
                EObject _currentModel_12 = context.getCurrentModel();
                if ((_currentModel_12 instanceof Expression)) {
                  EObject _currentModel_13 = context.getCurrentModel();
                  return this.isExpressionValidProposal(((Expression) _currentModel_13), proposal, result);
                }
              }
            }
          }
        }
      }
    }
    return result;
  }
  
  public boolean isExpressionValidProposal(final Expression expression, final String proposal, final boolean result) {
    EObject _eContainer = expression.eContainer();
    if ((_eContainer instanceof ConditionalExpression)) {
      EObject _eContainer_1 = expression.eContainer();
      Expression _left = ((ConditionalExpression) _eContainer_1).getLeft();
      if ((_left instanceof DatamartAttributeBase)) {
        EObject _eContainer_2 = expression.eContainer();
        Expression _left_1 = ((ConditionalExpression) _eContainer_2).getLeft();
        DatamartAttributeBase currentAttribute = ((DatamartAttributeBase) _left_1);
        LScalarType _type = currentAttribute.getAttributeRef().getType();
        LDataType type = ((LDataType) _type);
        if (("optional".equals(proposal) && (!"String".equals(type.getName())))) {
          return false;
        }
      }
    }
    return true;
  }
  
  public boolean isOrderValidProposal(final DatamartOrder currentOrder, final String proposal, final boolean result) {
    boolean _equals = proposal.equals("columnWeight");
    if (_equals) {
      return true;
    }
    List<OrderEnum> _list = IterableExtensions.<OrderEnum>toList(((Iterable<OrderEnum>)Conversions.doWrapArray(OrderEnum.values())));
    for (final OrderEnum e : _list) {
      boolean _equals_1 = e.getLiteral().equals(proposal);
      if (_equals_1) {
        return true;
      }
    }
    EObject eObj = currentOrder.eContainer();
    if ((eObj instanceof DatamartEntity)) {
      List<LEntityAttribute> _allAttributes = ((DatamartEntity) eObj).getEntityRef().getAllAttributes();
      for (final LEntityAttribute attribute : _allAttributes) {
        if (((attribute.getName().equals(proposal) && (!attribute.isId())) && (!attribute.isUuid()))) {
          return true;
        }
      }
    }
    return false;
  }
  
  public boolean isConditionalExpressionValidProposal(final ConditionalExpression currentConditionalExpression, final String proposal, final boolean result) {
    if (((proposal.equals("column") || proposal.equals("filter")) || proposal.equals("attribute"))) {
      return false;
    }
    if (((!currentConditionalExpression.getOperator().getLiteral().equals("=")) && ((proposal.equals("filtered") || proposal.equals("selected")) || proposal.equals("ranged")))) {
      return false;
    }
    return true;
  }
  
  public boolean isConditionValidProposal(final DatamartCondition currentCondition, final String proposal, final boolean result) {
    EObject eObj = currentCondition.eContainer();
    boolean _matched = false;
    if (eObj instanceof DatamartEntity) {
      _matched=true;
      if ((proposal.equals("column") || proposal.equals("filter"))) {
        return false;
      }
    }
    if (!_matched) {
      if (eObj instanceof DatamartTask) {
        _matched=true;
        boolean _equals = proposal.equals("attribute");
        if (_equals) {
          return false;
        }
      }
    }
    if (!_matched) {
      if (eObj instanceof DatamartCube) {
        _matched=true;
        if (((proposal.equals("column") || proposal.equals("filter")) || proposal.equals("attribute"))) {
          return false;
        }
      }
    }
    if (((proposal.equals("filtered") || proposal.equals("optional")) || proposal.equals("selected"))) {
      return false;
    }
    return true;
  }
  
  public boolean isAttributeValidProposal(final DatamartAttribute currentAttribute, final String proposal, final boolean result) {
    for (final AxisEnum idx : AxisEnumUtil.VALUES) {
      if ((proposal.equals(idx.getLiteral()) && ((idx.getValue() > 1) || (idx.getValue() < 0)))) {
        return false;
      }
    }
    boolean _equals = proposal.equals("aggregate");
    if (_equals) {
      LScalarType typeTemp = currentAttribute.getAttributeRef().getType();
      if (((!Objects.equal(typeTemp, null)) && (typeTemp instanceof LDataType))) {
        LDataType type = ((LDataType) typeTemp);
        JvmTypeReference _jvmTypeReference = type.getJvmTypeReference();
        boolean _equals_1 = Objects.equal(_jvmTypeReference, null);
        if (_equals_1) {
          return false;
        }
        if ((((!type.getJvmTypeReference().getSimpleName().equalsIgnoreCase("float")) && 
          (!type.getJvmTypeReference().getSimpleName().equalsIgnoreCase("double"))) && 
          (!type.getJvmTypeReference().getSimpleName().equalsIgnoreCase("integer")))) {
          return false;
        }
      } else {
        return false;
      }
    }
    return true;
  }
  
  public boolean isHierarchyValidProposal(final DatamartHierarchy currentHierarchy, final String proposal, final boolean result) {
    DatamartCubeAxis axis = null;
    DatamartSlicer slicer = null;
    EObject eObj = currentHierarchy.eContainer();
    while ((!(eObj instanceof DatamartCubeElement))) {
      eObj = eObj.eContainer();
    }
    boolean _notEquals = (!Objects.equal(eObj, null));
    if (_notEquals) {
      if ((eObj instanceof DatamartCubeAxis)) {
        axis = ((DatamartCubeAxis) eObj);
        if (((!Objects.equal(axis, null)) && (!Objects.equal(axis.getElements(), null)))) {
          EList<DatamartElement> _elements = axis.getElements();
          for (final DatamartElement element : _elements) {
            {
              if ((element instanceof DatamartHierarchy)) {
                if (((!Objects.equal(((DatamartHierarchy) element).getHierarchyRef(), null)) && 
                  (!Objects.equal(((DatamartHierarchy) element).getHierarchyRef(), currentHierarchy)))) {
                  boolean _equals = proposal.equals(((DatamartHierarchy) element).getHierarchyRef().getName());
                  if (_equals) {
                    return true;
                  }
                }
                boolean _equals_1 = proposal.equals("detailed");
                if (_equals_1) {
                  return true;
                }
                if (((proposal.equals("condensed") || proposal.equals("default")) || 
                  proposal.equals("exploded"))) {
                  CubeLevel _levelRef = ((DatamartHierarchy) element).getLevelRef();
                  boolean _notEquals_1 = (!Objects.equal(_levelRef, null));
                  if (_notEquals_1) {
                    return false;
                  }
                }
                boolean _equals_2 = proposal.equals("selected");
                if (_equals_2) {
                  return false;
                }
                return true;
              }
              if ((element instanceof DatamartMeasure)) {
                CubeMeasure _measureRef = ((DatamartMeasure) element).getMeasureRef();
                boolean _notEquals_2 = (!Objects.equal(_measureRef, null));
                if (_notEquals_2) {
                  boolean _equals_3 = proposal.equals(((DatamartMeasure) element).getMeasureRef().getName());
                  if (_equals_3) {
                    return false;
                  }
                }
              }
              return true;
            }
          }
        }
      }
      if ((eObj instanceof DatamartSlicer)) {
        slicer = ((DatamartSlicer) eObj);
        if (((!Objects.equal(slicer, null)) && (!Objects.equal(slicer.getElement(), null)))) {
          DatamartElement element_1 = slicer.getElement();
          if ((element_1 instanceof DatamartHierarchy)) {
            if (((!Objects.equal(((DatamartHierarchy) element_1).getHierarchyRef(), null)) && 
              (!Objects.equal(((DatamartHierarchy) element_1).getHierarchyRef(), currentHierarchy)))) {
              boolean _equals = proposal.equals(((DatamartHierarchy) element_1).getHierarchyRef().getName());
              if (_equals) {
                return true;
              }
            }
            return true;
          }
          if ((element_1 instanceof DatamartMeasure)) {
            CubeMeasure _measureRef = ((DatamartMeasure) element_1).getMeasureRef();
            boolean _notEquals_1 = (!Objects.equal(_measureRef, null));
            if (_notEquals_1) {
              boolean _equals_1 = proposal.equals(((DatamartMeasure) element_1).getMeasureRef().getName());
              if (_equals_1) {
                return false;
              }
            }
          }
          return true;
        }
      }
      if ((eObj instanceof DatamartDefineDerivedMeasure)) {
        return true;
      }
    }
    return false;
  }
  
  public boolean isAxisValidProposal(final DatamartAxis currentAxis, final String proposal, final boolean result) {
    boolean _equals = "{".equals(proposal);
    if (_equals) {
      return true;
    }
    boolean _equals_1 = "}".equals(proposal);
    if (_equals_1) {
      return true;
    }
    EObject eObj = currentAxis.eContainer().eContainer();
    DatamartCubeAxis axisWithMeasure = null;
    boolean _notEquals = (!Objects.equal(eObj, null));
    if (_notEquals) {
      if ((eObj instanceof DatamartCube)) {
        int idx = 0;
        EList<DatamartCubeElement> _axisslicer = ((DatamartCube) eObj).getAxisslicer();
        for (final DatamartCubeElement axisslicer : _axisslicer) {
          if ((axisslicer instanceof DatamartCubeAxis)) {
            EList<DatamartElement> _elements = ((DatamartCubeAxis) axisslicer).getElements();
            for (final DatamartElement element : _elements) {
              if (((element instanceof DatamartMeasure) || (element instanceof DatamartDerivedMeasure))) {
                axisWithMeasure = ((DatamartCubeAxis) axisslicer);
              }
            }
            idx = (idx + 1);
          }
        }
        idx = 0;
        int axisOrdinal = 0;
        EList<DatamartCubeElement> _axisslicer_1 = ((DatamartCube) eObj).getAxisslicer();
        for (final DatamartCubeElement axisslicer_1 : _axisslicer_1) {
          if ((axisslicer_1 instanceof DatamartCubeAxis)) {
            EObject _eContainer = currentAxis.eContainer();
            boolean _equals_2 = Objects.equal(axisslicer_1, _eContainer);
            if (_equals_2) {
              axisOrdinal = idx;
            }
            idx = (idx + 1);
          }
        }
        String orderedProposal = AxisEnumUtil.get(axisOrdinal).getLiteral();
        boolean _equals_3 = proposal.equals(orderedProposal);
        if (_equals_3) {
          return true;
        }
      }
      if ((eObj instanceof DatamartEntity)) {
        return true;
      }
    }
    for (final SetAggregationEnum setAggregation : SetAggregationEnumUtil.VALUES) {
      boolean _equals_4 = setAggregation.getLiteral().equals(proposal);
      if (_equals_4) {
        return true;
      }
    }
    boolean _equals_5 = proposal.equals("hierarchy");
    if (_equals_5) {
      return true;
    }
    if (((proposal.equals("measure") || proposal.equals("derived")) && (Objects.equal(axisWithMeasure, null) || Objects.equal(axisWithMeasure, currentAxis)))) {
      return true;
    }
    return false;
  }
  
  @Override
  public void complete_QualifiedName(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this);
  }
  
  @Override
  public void complete_TRANSLATABLESTRING(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_STRING(model, ruleCall, context, acceptor);
  }
  
  @Override
  public void complete_TRANSLATABLEID(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_ID(model, ruleCall, context, acceptor);
  }
  
  @Override
  public void complete_ID(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_ID(model, ruleCall, context, acceptor);
  }
  
  @Override
  public void complete_INT(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_INT(model, ruleCall, context, acceptor);
  }
}
