/**
 * 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.xtext.basic.validation.IBasicValidatorDelegate;
import org.eclipse.osbp.xtext.datamartdsl.AxisEnum;
import org.eclipse.osbp.xtext.datamartdsl.DatamartAttribute;
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.DatamartEntity;
import org.eclipse.osbp.xtext.datamartdsl.DatamartSource;
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask;
import org.eclipse.osbp.xtext.datamartdsl.util.DatamartAttributeUtil;
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.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;
  
  @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);
    }
  }
}
