/**
 * 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 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
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 */
package org.eclipse.osbp.xtext.perspective.validation;

import java.util.HashSet;
import java.util.function.Consumer;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.osbp.xtext.blip.Blip;
import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveElement;
import org.eclipse.osbp.xtext.perspective.PerspectiveEvent;
import org.eclipse.osbp.xtext.perspective.PerspectiveEventManager;
import org.eclipse.osbp.xtext.perspective.PerspectivePackage;
import org.eclipse.osbp.xtext.perspective.PerspectivePart;
import org.eclipse.osbp.xtext.perspective.validation.AbstractPerspectiveDslValidator;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.xbase.lib.Exceptions;

/**
 * Custom validation rules.
 * 
 * see http://www.eclipse.org/Xtext/documentation.html#validation
 */
@SuppressWarnings("all")
public class PerspectiveDslValidator extends AbstractPerspectiveDslValidator {
  @Check
  public void checkBPMlicensed(final Perspective pers) {
    try {
      Blip _process = pers.getProcess();
      boolean _tripleNotEquals = (_process != null);
      if (_tripleNotEquals) {
        ResourceSet _resourceSet = pers.eResource().getResourceSet();
        final XtextResourceSet rs = ((XtextResourceSet) _resourceSet);
        Object _classpathURIContext = rs.getClasspathURIContext();
        if ((_classpathURIContext instanceof JavaProject)) {
          Object _classpathURIContext_1 = rs.getClasspathURIContext();
          final JavaProject javaProject = ((JavaProject) _classpathURIContext_1);
          IType found = javaProject.findType("net.osbee.bpm.BPMEngine");
          if ((found == null)) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("BPM is needed and not yet licensed. License BPM at www.osbee.net");
            this.info(_builder.toString(), pers, 
              PerspectiveDslPackage.Literals.PERSPECTIVE__PROCESS);
          }
        }
      }
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForDuplicatedPerspectiveNames(final PerspectivePackage perspectivePackage) {
    HashSet<String> names = new HashSet<String>();
    int counter = 0;
    EList<Perspective> _perspectives = perspectivePackage.getPerspectives();
    for (final Perspective pers : _perspectives) {
      {
        String name = pers.getName();
        boolean _add = names.add(name);
        boolean _not = (!_add);
        if (_not) {
          this.error(String.format("Perspective %s must be unique in package %s!", name, perspectivePackage.getName()), 
            PerspectiveDslPackage.Literals.PERSPECTIVE_PACKAGE__PERSPECTIVES, counter);
          return;
        }
        counter++;
      }
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForDuplicatedPerspectiveElementNames(final Perspective perspective) {
    HashSet<String> elementIds = new HashSet<String>();
    int counter = 0;
    EList<PerspectiveElement> _elements = perspective.getElements();
    for (final PerspectiveElement element : _elements) {
      {
        String elementId = element.getElementId();
        boolean _add = elementIds.add(elementId);
        boolean _not = (!_add);
        if (_not) {
          this.error(String.format("Perspective element %s must be unique in perspective %s!", elementId, perspective.getName()), 
            PerspectiveDslPackage.Literals.PERSPECTIVE__ELEMENTS, counter);
          return;
        }
        counter++;
      }
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForDuplicatedPerspectiveElementNames(final PerspectiveElement perspectiveElement) {
    HashSet<String> elementIds = new HashSet<String>();
    int counter = 0;
    EList<PerspectiveElement> _elements = perspectiveElement.getElements();
    for (final PerspectiveElement element : _elements) {
      {
        String elementId = element.getElementId();
        boolean _add = elementIds.add(elementId);
        boolean _not = (!_add);
        if (_not) {
          this.error(String.format("Perspective element %s must be unique in perspective element %s!", elementId, perspectiveElement.getElementId()), 
            PerspectiveDslPackage.Literals.PERSPECTIVE_ELEMENT__ELEMENTS, counter);
          return;
        }
        counter++;
      }
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForDuplicatePerspectiveEventTarget(final PerspectiveEventManager manager) {
    final HashSet<String> elementIds = new HashSet<String>();
    if (((manager.getEvents() != null) && (!manager.getEvents().isEmpty()))) {
      final Consumer<PerspectiveEvent> _function = (PerspectiveEvent it) -> {
        boolean _add = elementIds.add(it.getTarget().getElementId());
        boolean _not = (!_add);
        if (_not) {
          this.error(String.format("The target event part %s can only be used once!", it.getTarget().getElementId()), it, PerspectiveDslPackage.Literals.PERSPECTIVE_EVENT__TARGET);
        }
      };
      manager.getEvents().forEach(_function);
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForDuplicatedPerspectiveEventSenders(final PerspectiveEvent event) {
    HashSet<String> elementIds = new HashSet<String>();
    int counter = 0;
    EList<PerspectivePart> _allowedsources = event.getAllowedsources();
    for (final PerspectivePart source : _allowedsources) {
      {
        String elementId = source.getElementId();
        boolean _add = elementIds.add(elementId);
        boolean _not = (!_add);
        if (_not) {
          this.error(String.format("The source event part %s can only be used once!", elementId), event, PerspectiveDslPackage.Literals.PERSPECTIVE_EVENT__ALLOWEDSOURCES);
          return;
        }
        counter++;
      }
    }
  }
  
  @Check(CheckType.NORMAL)
  public void checkForPerspectiveEventSenderCount(final PerspectiveEvent event) {
    if ((((event.getTarget() != null) && (event.getAllowedsources() == null)) || event.getAllowedsources().isEmpty())) {
      this.error("You must define at least one source event part!", event, PerspectiveDslPackage.Literals.PERSPECTIVE_EVENT__ALLOWEDSOURCES);
    }
  }
}
