/**
 * 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 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
 */
package org.eclipse.osbp.xtext.datamartdsl.validation;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.xtext.basic.validation.IBasicValidatorDelegate;
import org.eclipse.osbp.xtext.datamartdsl.AxisEnum;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttributeBase;
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.DatamartDSLPackage;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition;
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.DatamartHierarchyLevel;
import org.eclipse.osbp.xtext.datamartdsl.DatamartHierarchyLevelMultiple;
import org.eclipse.osbp.xtext.datamartdsl.DatamartHierarchyLevelSingle;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSetFunction;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSetFunctionInterface;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSetTuple;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSource;
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask;
import org.eclipse.osbp.xtext.datamartdsl.SetFunctionEnum;
import org.eclipse.osbp.xtext.datamartdsl.util.DatamartAttributeUtil;
import org.eclipse.osbp.xtext.datamartdsl.util.DatamartHierarchyUtil;
import org.eclipse.osbp.xtext.datamartdsl.validation.AbstractDatamartDSLValidator;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * Custom validation rules.
 * 
 * see http://www.eclipse.org/Xtext/documentation.html#validation
 */
@SuppressWarnings("all")
public class DatamartDSLValidator extends AbstractDatamartDSLValidator {
  @Inject(optional = true)
  private IBasicValidatorDelegate delegate;
  
  @Inject
  @Extension
  private DatamartHierarchyUtil _datamartHierarchyUtil;
  
  @Check
  public void checkCommercialLicensed(final DatamartDefinition datamart) {
    DatamartSource _source = datamart.getSource();
    if ((_source instanceof DatamartTask)) {
      if (((this.delegate != null) && (!this.delegate.validateCommercial("datamart", "net.osbee.bpm")))) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("BPM is needed and not yet licensed. License BPM at www.osbee.net");
        this.info(_builder.toString(), datamart, null);
      }
    }
    DatamartSource _source_1 = datamart.getSource();
    if ((_source_1 instanceof DatamartCube)) {
      if (((this.delegate != null) && (!this.delegate.validateCommercial("datamart", "net.osbee.xtext.cube")))) {
        StringConcatenation _builder_1 = new StringConcatenation();
        _builder_1.append("Cube is needed and not yet licensed. License Cube at www.osbee.net");
        this.info(_builder_1.toString(), datamart, null);
      }
    }
  }
  
  @Check
  public void checkForDuplicatedAttributeNamesOrAliases(final DatamartAttribute attribute) {
    HashSet<String> attributeNames = CollectionLiterals.<String>newHashSet();
    EObject eObj = attribute.eContainer();
    while (((eObj != null) && (!(eObj instanceof DatamartEntity)))) {
      eObj = eObj.eContainer();
    }
    if ((eObj != null)) {
      this.checkForDuplicatedAttributeNamesOrAliases(((DatamartEntity) eObj), attributeNames);
    }
  }
  
  private void checkForDuplicatedAttributeNamesOrAliases(final DatamartEntity entity, final Set<String> attributeNames) {
    boolean error = false;
    EList<DatamartAttribute> _attributes = entity.getAttributes();
    for (final DatamartAttribute attribute : _attributes) {
      {
        boolean added = attributeNames.add(DatamartAttributeUtil.getAliasedAttributeName(attribute));
        if ((!added)) {
          error = true;
          StringConcatenation _builder = new StringConcatenation();
          _builder.append("Duplicated attribute names or aliases are not allowed in the same datamart definition.");
          String errorTxt = _builder.toString();
          boolean _isAliased = attribute.isAliased();
          if (_isAliased) {
            this.error(errorTxt, attribute, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE__ALIAS_NAME);
          } else {
            this.error(errorTxt, attribute, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE_BASE__ATTRIBUTE_REF);
          }
        }
      }
    }
    if ((!error)) {
      EObject eObj = entity.eContainer();
      while (((eObj != null) && (!(eObj instanceof DatamartEntity)))) {
        eObj = eObj.eContainer();
      }
      if ((eObj != null)) {
        this.checkForDuplicatedAttributeNamesOrAliases(((DatamartEntity) eObj), attributeNames);
      }
    }
  }
  
  /**
   * Checks if both axis "rows" and "columns" are defined when a DatamartCube definition contains either the axis "pages", "chapters" "sections" or all 3 of them.
   */
  @Check
  public void checkForRowsAndColumnsPresenceInCube(final DatamartCube cube) {
    boolean error = false;
    final Function1<DatamartCubeElement, Boolean> _function = (DatamartCubeElement it) -> {
      return Boolean.valueOf(((it instanceof DatamartCubeAxis) && Objects.equal(((DatamartCubeAxis) it).getAxis().getName(), AxisEnum.COLUMNS)));
    };
    boolean hasAxisColumns = IterableExtensions.<DatamartCubeElement>exists(cube.getAxisslicer(), _function);
    final Function1<DatamartCubeElement, Boolean> _function_1 = (DatamartCubeElement it) -> {
      return Boolean.valueOf(((it instanceof DatamartCubeAxis) && Objects.equal(((DatamartCubeAxis) it).getAxis().getName(), AxisEnum.ROWS)));
    };
    boolean hasAxisRows = IterableExtensions.<DatamartCubeElement>exists(cube.getAxisslicer(), _function_1);
    final Function1<DatamartCubeElement, Boolean> _function_2 = (DatamartCubeElement it) -> {
      return Boolean.valueOf(((it instanceof DatamartCubeAxis) && Objects.equal(((DatamartCubeAxis) it).getAxis().getName(), AxisEnum.PAGES)));
    };
    DatamartCubeElement axisPages = IterableExtensions.<DatamartCubeElement>findFirst(cube.getAxisslicer(), _function_2);
    final Function1<DatamartCubeElement, Boolean> _function_3 = (DatamartCubeElement it) -> {
      return Boolean.valueOf(((it instanceof DatamartCubeAxis) && Objects.equal(((DatamartCubeAxis) it).getAxis().getName(), AxisEnum.CHAPTERS)));
    };
    DatamartCubeElement axisChapters = IterableExtensions.<DatamartCubeElement>findFirst(cube.getAxisslicer(), _function_3);
    final Function1<DatamartCubeElement, Boolean> _function_4 = (DatamartCubeElement it) -> {
      return Boolean.valueOf(((it instanceof DatamartCubeAxis) && Objects.equal(((DatamartCubeAxis) it).getAxis().getName(), AxisEnum.SECTIONS)));
    };
    DatamartCubeElement axisSections = IterableExtensions.<DatamartCubeElement>findFirst(cube.getAxisslicer(), _function_4);
    if ((((axisPages != null) && (!hasAxisColumns)) || ((axisPages != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(" ");
      _builder.append("\"pages\" can\'t be used without setting up both \"columns\" and \"rows\".");
      String errorTxt = _builder.toString();
      this.error(errorTxt, axisPages, DatamartDSLPackage.Literals.DATAMART_CUBE_AXIS__AXIS);
    }
    if ((((axisChapters != null) && (!hasAxisColumns)) || ((axisChapters != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder_1 = new StringConcatenation();
      _builder_1.append(" ");
      _builder_1.append("\'\'chapters\'\' can\'t be used without setting up both \'\'columns\'\' and \'\'rows\'\'.");
      String errorTxt_1 = _builder_1.toString();
      this.error(errorTxt_1, axisChapters, DatamartDSLPackage.Literals.DATAMART_CUBE_AXIS__AXIS);
    }
    if ((((axisSections != null) && (!hasAxisColumns)) || ((axisSections != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder_2 = new StringConcatenation();
      _builder_2.append(" ");
      _builder_2.append("\'\'sections\'\' can\'t be used without setting up both \'\'columns\'\' and \'\'rows\'\'.");
      String errorTxt_2 = _builder_2.toString();
      this.error(errorTxt_2, axisSections, DatamartDSLPackage.Literals.DATAMART_CUBE_AXIS__AXIS);
    }
  }
  
  /**
   * Checks if both axis "rows" and "columns" are defined when a DatamartEntity definition contains either the axis "pages", "chapters" "sections" or all 3 of them.
   */
  @Check
  public void checkForRowsAndColumnsPresenceInEntity(final DatamartEntity entity) {
    boolean error = false;
    final Function1<DatamartAttribute, Boolean> _function = (DatamartAttribute it) -> {
      return Boolean.valueOf(((it instanceof DatamartAttribute) && Objects.equal(((DatamartAttribute) it).getAxis().getName(), AxisEnum.COLUMNS)));
    };
    boolean hasAxisColumns = IterableExtensions.<DatamartAttribute>exists(entity.getAttributes(), _function);
    final Function1<DatamartAttribute, Boolean> _function_1 = (DatamartAttribute it) -> {
      return Boolean.valueOf(((it instanceof DatamartAttribute) && Objects.equal(((DatamartAttribute) it).getAxis().getName(), AxisEnum.ROWS)));
    };
    boolean hasAxisRows = IterableExtensions.<DatamartAttribute>exists(entity.getAttributes(), _function_1);
    final Function1<DatamartAttribute, Boolean> _function_2 = (DatamartAttribute it) -> {
      return Boolean.valueOf(((it instanceof DatamartAttribute) && Objects.equal(((DatamartAttribute) it).getAxis().getName(), AxisEnum.PAGES)));
    };
    DatamartAttribute axisPages = IterableExtensions.<DatamartAttribute>findFirst(entity.getAttributes(), _function_2);
    final Function1<DatamartAttribute, Boolean> _function_3 = (DatamartAttribute it) -> {
      return Boolean.valueOf(((it instanceof DatamartAttribute) && Objects.equal(((DatamartAttribute) it).getAxis().getName(), AxisEnum.CHAPTERS)));
    };
    DatamartAttribute axisChapters = IterableExtensions.<DatamartAttribute>findFirst(entity.getAttributes(), _function_3);
    final Function1<DatamartAttribute, Boolean> _function_4 = (DatamartAttribute it) -> {
      return Boolean.valueOf(((it instanceof DatamartAttribute) && Objects.equal(((DatamartAttribute) it).getAxis().getName(), AxisEnum.SECTIONS)));
    };
    DatamartAttribute axisSections = IterableExtensions.<DatamartAttribute>findFirst(entity.getAttributes(), _function_4);
    if ((((axisPages != null) && (!hasAxisColumns)) || ((axisPages != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(" ");
      _builder.append("\'\'pages\'\' can\'t be used without setting up both \'\'columns\'\' and \'\'rows\'\'.");
      String errorTxt = _builder.toString();
      this.error(errorTxt, axisPages, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE__AXIS);
    }
    if ((((axisChapters != null) && (!hasAxisColumns)) || ((axisChapters != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder_1 = new StringConcatenation();
      _builder_1.append(" ");
      _builder_1.append("\'\'chapters\'\' can\'t be used without setting up both \'\'columns\'\' and \'\'rows\'\'.");
      String errorTxt_1 = _builder_1.toString();
      this.error(errorTxt_1, axisChapters, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE__AXIS);
    }
    if ((((axisSections != null) && (!hasAxisColumns)) || ((axisSections != null) && (!hasAxisRows)))) {
      error = true;
      StringConcatenation _builder_2 = new StringConcatenation();
      _builder_2.append(" ");
      _builder_2.append("\'\'sections\'\' can\'t be used without setting up both \'\'columns\'\' and \'\'rows\'\'.");
      String errorTxt_2 = _builder_2.toString();
      this.error(errorTxt_2, axisSections, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE__AXIS);
    }
  }
  
  /**
   * Checks that no transient attribute is used.
   */
  @Check
  public void checkForTransientAttribute(final DatamartAttributeBase attribute) {
    final LEntityAttribute entityAttribute = attribute.getAttributeRef();
    boolean error = false;
    if ((entityAttribute.eIsProxy() || ((!entityAttribute.eIsProxy()) && entityAttribute.isTransient()))) {
      error = true;
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(" ");
      _builder.append("\'\'attribute\'\' can\'t refer to an unresolved or transient entity attribute.");
      String errorTxt = _builder.toString();
      this.error(errorTxt, attribute, DatamartDSLPackage.Literals.DATAMART_ATTRIBUTE_BASE__ATTRIBUTE_REF);
    }
  }
  
  /**
   * Checks that two same hierarchies are not used in the same datamart axis row definition.
   */
  @Check
  public void checkForUniqueHierarchy(final DatamartHierarchy hierarchy) {
    boolean error = false;
    EObject parent = hierarchy.eContainer();
    if ((parent instanceof DatamartCubeAxis)) {
      int hierarchiesFound = 0;
      EList<DatamartElement> _elements = ((DatamartCubeAxis) parent).getElements();
      for (final DatamartElement element : _elements) {
        {
          if ((element instanceof DatamartHierarchy)) {
            boolean _equals = hierarchy.getHierarchyRef().getName().equals(((DatamartHierarchy) element).getHierarchyRef().getName());
            if (_equals) {
              hierarchiesFound++;
            }
          }
          if ((hierarchiesFound > 1)) {
            error = true;
            StringConcatenation _builder = new StringConcatenation();
            _builder.append(" ");
            _builder.append("\'\'hierarchy\'\' can\'t refer to more than one member of the same hierarchy.");
            String errorTxt = _builder.toString();
            this.error(errorTxt, hierarchy, DatamartDSLPackage.Literals.DATAMART_HIERARCHY__HIERARCHY_REF);
          }
        }
      }
    }
  }
  
  @Check
  public void checkNoLevelInYtd(final DatamartHierarchy hierarchy) {
    EObject eObject = hierarchy.eContainer();
    while (((eObject != null) && (!(eObject instanceof DatamartSetTuple)))) {
      eObject = eObject.eContainer();
    }
    if ((eObject != null)) {
      DatamartSetFunctionInterface function = ((DatamartSetTuple) eObject).getLeft().getSetFunction();
      if (((function instanceof DatamartSetFunction) && SetFunctionEnum.YTD.equals(((DatamartSetFunction) function).getSetFunction()))) {
        boolean _existLevelDefinition = this._datamartHierarchyUtil.existLevelDefinition(hierarchy);
        if (_existLevelDefinition) {
          StringConcatenation _builder = new StringConcatenation();
          _builder.append(" ");
          _builder.append("\'\'hierarchy\'\' can\'t define a level as part of the \'");
          String _literal = SetFunctionEnum.YTD.getLiteral();
          _builder.append(_literal, " ");
          _builder.append("\' function. Please remove the complete level.");
          String errorTxt = _builder.toString();
          this.error(errorTxt, hierarchy, DatamartDSLPackage.Literals.DATAMART_HIERARCHY_LEVEL_SINGLE__LEVEL_REF);
        }
      }
    }
  }
  
  @Check
  public void checkSortedInLevel(final DatamartHierarchyLevel hierarchyLevel) {
    if ((hierarchyLevel instanceof DatamartHierarchyLevelMultiple)) {
      int sorted = 0;
      EList<DatamartHierarchyLevelSingle> _levels = ((DatamartHierarchyLevelMultiple)hierarchyLevel).getLevels();
      for (final DatamartHierarchyLevelSingle level : _levels) {
        {
          boolean _isSorted = level.isSorted();
          if (_isSorted) {
            sorted++;
          }
          if ((sorted > 1)) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append(" ");
            _builder.append("Only one level is allowed to have the \'\'sorted\'\' attribute. Please remain only one \'\'sorted\'\' attribute.");
            String errorTxt = _builder.toString();
            this.error(errorTxt, hierarchyLevel, DatamartDSLPackage.Literals.DATAMART_HIERARCHY_LEVEL_SINGLE__SORTED);
          }
        }
      }
    } else {
      EObject _eContainer = hierarchyLevel.eContainer();
      boolean _not = (!(_eContainer instanceof DatamartHierarchyLevelMultiple));
      if (_not) {
        if (((hierarchyLevel instanceof DatamartHierarchyLevelSingle) && ((DatamartHierarchyLevelSingle) hierarchyLevel).isSorted())) {
          StringConcatenation _builder = new StringConcatenation();
          _builder.append(" ");
          _builder.append("Only a level of a hierarchized hierarchy is allowed to have the \'\'sorted\'\' attribute. Please remove it.");
          String errorTxt = _builder.toString();
          this.error(errorTxt, hierarchyLevel, DatamartDSLPackage.Literals.DATAMART_HIERARCHY_LEVEL_SINGLE__SORTED);
        }
      }
    }
  }
}
