/**
 * 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.blip.common;

import com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.bpm.NamingConvention;
import org.eclipse.osbp.dsl.semantic.common.types.LMultiplicity;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.dto.LAutoInheritDto;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractReference;
import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature;
import org.eclipse.osbp.dsl.semantic.dto.impl.LDtoInheritedReferenceImpl;
import org.eclipse.osbp.dsl.semantic.dto.impl.LDtoReferenceImpl;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.xtext.blip.Blip;
import org.eclipse.osbp.xtext.blip.BlipCallActivity;
import org.eclipse.osbp.xtext.blip.BlipDto;
import org.eclipse.osbp.xtext.blip.BlipDtoPath;
import org.eclipse.osbp.xtext.blip.BlipEvent;
import org.eclipse.osbp.xtext.blip.BlipItem;
import org.eclipse.osbp.xtext.blip.BlipOutGoing;
import org.eclipse.osbp.xtext.blip.BlipScript;
import org.eclipse.osbp.xtext.blip.BlipServiceTask;
import org.eclipse.osbp.xtext.blip.BlipSplitGateway;
import org.eclipse.osbp.xtext.blip.BlipUserTask;
import org.eclipse.osbp.xtext.blip.BlipWorkload;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;

@SuppressWarnings("all")
public class BlipHelper {
  public static String getBpmItemRecommendedName(final BlipItem blipItem) {
    String bpmItemName = "";
    if ((blipItem instanceof BlipEvent)) {
      bpmItemName = ((BlipEvent)blipItem).getEvent().getName();
    } else {
      if ((blipItem instanceof BlipSplitGateway)) {
        bpmItemName = ((BlipSplitGateway)blipItem).getGateway().getName();
      } else {
        if ((blipItem instanceof BlipUserTask)) {
          bpmItemName = ((BlipUserTask)blipItem).getTask().getName();
        } else {
          if ((blipItem instanceof BlipCallActivity)) {
            bpmItemName = ((BlipCallActivity)blipItem).getCallActivity().getName();
          } else {
            if ((blipItem instanceof BlipScript)) {
              bpmItemName = ((BlipScript)blipItem).getTask().getName();
            } else {
              if ((blipItem instanceof BlipServiceTask)) {
                bpmItemName = ((BlipServiceTask)blipItem).getTask().getName();
              } else {
                if ((blipItem instanceof BlipOutGoing)) {
                  bpmItemName = ((BlipOutGoing)blipItem).getSequenceFlow().getName();
                }
              }
            }
          }
        }
      }
    }
    return NamingConvention.getBpmItemRecommendedName(bpmItemName);
  }
  
  public static boolean isOperativeDtoDefined(final BlipItem blipItem) {
    boolean _and = false;
    BlipDtoPath _dtoPath = null;
    if (blipItem!=null) {
      _dtoPath=blipItem.getDtoPath();
    }
    boolean _notEquals = (!Objects.equal(_dtoPath, null));
    if (!_notEquals) {
      _and = false;
    } else {
      BlipDtoPath _dtoPath_1 = null;
      if (blipItem!=null) {
        _dtoPath_1=blipItem.getDtoPath();
      }
      boolean _isEmpty = _dtoPath_1.getDtoPath().isEmpty();
      boolean _not = (!_isEmpty);
      _and = _not;
    }
    return _and;
  }
  
  public static LDtoAbstractReference getDtoFeature(final LDto operativeDto, final String dtoChildName) {
    boolean _notEquals = (!Objects.equal(operativeDto, null));
    if (_notEquals) {
      EList<LDtoFeature> _features = operativeDto.getFeatures();
      for (final LDtoFeature feature : _features) {
        {
          String attributeName = ((String) null);
          if ((feature instanceof LDtoReferenceImpl)) {
            attributeName = ((LDtoReferenceImpl)feature).getName();
          }
          if ((feature instanceof LDtoInheritedReferenceImpl)) {
            attributeName = ((LDtoInheritedReferenceImpl)feature).getInheritedFeature().getName();
          }
          boolean _notEquals_1 = (!Objects.equal(attributeName, null));
          if (_notEquals_1) {
            if ((attributeName.equals(dtoChildName) && (feature instanceof LDtoAbstractReference))) {
              return ((LDtoAbstractReference) feature);
            }
          }
        }
      }
    }
    return null;
  }
  
  public static LDto getPureOperativeLDto(final BlipItem blipItem) {
    boolean _isOperativeDtoDefined = BlipHelper.isOperativeDtoDefined(blipItem);
    if (_isOperativeDtoDefined) {
      EObject _eContainer = null;
      if (blipItem!=null) {
        _eContainer=blipItem.eContainer();
      }
      BlipWorkload _workload = null;
      if (((Blip) _eContainer)!=null) {
        _workload=((Blip) _eContainer).getWorkload();
      }
      BlipDto _source = null;
      if (_workload!=null) {
        _source=_workload.getSource();
      }
      LDto _dtoRef = null;
      if (_source!=null) {
        _dtoRef=_source.getDtoRef();
      }
      LDto operativeDto = _dtoRef;
      boolean _and = false;
      if (!((!Objects.equal(operativeDto, null)) && (!Objects.equal(operativeDto.getName(), null)))) {
        _and = false;
      } else {
        String _name = operativeDto.getName();
        BlipDtoPath _dtoPath = null;
        if (blipItem!=null) {
          _dtoPath=blipItem.getDtoPath();
        }
        boolean _equals = _name.equals(_dtoPath);
        boolean _not = (!_equals);
        _and = _not;
      }
      if (_and) {
        BlipDtoPath _dtoPath_1 = null;
        if (blipItem!=null) {
          _dtoPath_1=blipItem.getDtoPath();
        }
        String dtoPath = _dtoPath_1.getDtoPath();
        String _name_1 = operativeDto.getName();
        String _plus = (_name_1 + ".");
        boolean _startsWith = dtoPath.startsWith(_plus);
        boolean _not_1 = (!_startsWith);
        if (_not_1) {
          return null;
        } else {
          String _name_2 = operativeDto.getName();
          dtoPath = dtoPath.substring((_name_2 + ".").length());
          final String[] dtoChildNames = dtoPath.split("\\.");
          for (final String dtoChildName : dtoChildNames) {
            operativeDto = BlipHelper.getReferencedLDto(operativeDto, dtoChildName);
          }
        }
      }
      return operativeDto;
    }
    return null;
  }
  
  public static LDtoAbstractReference getDtoFeature(final BlipItem blipItem) {
    LDtoAbstractReference dtoFeature = ((LDtoAbstractReference) null);
    LDto operativeDto = ((LDto) null);
    boolean _isOperativeDtoDefined = BlipHelper.isOperativeDtoDefined(blipItem);
    if (_isOperativeDtoDefined) {
      EObject _eContainer = null;
      if (blipItem!=null) {
        _eContainer=blipItem.eContainer();
      }
      BlipWorkload _workload = null;
      if (((Blip) _eContainer)!=null) {
        _workload=((Blip) _eContainer).getWorkload();
      }
      BlipDto _source = null;
      if (_workload!=null) {
        _source=_workload.getSource();
      }
      LDto _dtoRef = null;
      if (_source!=null) {
        _dtoRef=_source.getDtoRef();
      }
      operativeDto = _dtoRef;
      boolean _and = false;
      if (!((!Objects.equal(operativeDto, null)) && (!Objects.equal(operativeDto.getName(), null)))) {
        _and = false;
      } else {
        String _name = operativeDto.getName();
        BlipDtoPath _dtoPath = null;
        if (blipItem!=null) {
          _dtoPath=blipItem.getDtoPath();
        }
        boolean _equals = _name.equals(_dtoPath);
        boolean _not = (!_equals);
        _and = _not;
      }
      if (_and) {
        BlipDtoPath _dtoPath_1 = null;
        if (blipItem!=null) {
          _dtoPath_1=blipItem.getDtoPath();
        }
        String _dtoPath_2 = _dtoPath_1.getDtoPath();
        String _name_1 = operativeDto.getName();
        String _plus = (_name_1 + ".");
        final String[] dtoChildNames = _dtoPath_2.replace(_plus, "").split("\\.");
        for (final String dtoChildName : dtoChildNames) {
          {
            dtoFeature = BlipHelper.getDtoFeature(operativeDto, dtoChildName);
            operativeDto = BlipHelper.getReferencedLDto(operativeDto, dtoChildName);
          }
        }
      }
    }
    return dtoFeature;
  }
  
  public static LEntity getOperativeEntity(final BlipItem blipItem) {
    LDto dto = blipItem.getOperativeLDto();
    if ((dto instanceof LAutoInheritDto)) {
      LType _wrappedType = ((LAutoInheritDto)dto).getWrappedType();
      if ((_wrappedType instanceof LEntity)) {
        LType _wrappedType_1 = ((LAutoInheritDto)dto).getWrappedType();
        return ((LEntity) _wrappedType_1);
      }
    }
    return null;
  }
  
  public static LDto getOperativeLDto(final BlipItem blipItem) {
    final LDto operativeDto = BlipHelper.getPureOperativeLDto(blipItem);
    boolean _equals = Objects.equal(operativeDto, null);
    if (_equals) {
      EObject _eContainer = null;
      if (blipItem!=null) {
        _eContainer=blipItem.eContainer();
      }
      BlipWorkload _workload = null;
      if (((Blip) _eContainer)!=null) {
        _workload=((Blip) _eContainer).getWorkload();
      }
      BlipDto _source = null;
      if (_workload!=null) {
        _source=_workload.getSource();
      }
      LDto _dtoRef = null;
      if (_source!=null) {
        _dtoRef=_source.getDtoRef();
      }
      return _dtoRef;
    } else {
      return operativeDto;
    }
  }
  
  public static LDto getReferencedLDto(final LDto operativeDto, final String dtoChildName) {
    LDtoAbstractReference dtoFeature = BlipHelper.getDtoFeature(operativeDto, dtoChildName);
    boolean _notEquals = (!Objects.equal(dtoFeature, null));
    if (_notEquals) {
      return dtoFeature.getType();
    }
    return null;
  }
  
  public static List<String> getAvailableDtoPaths(final BlipItem blipItem) {
    EObject _eContainer = blipItem.eContainer();
    return BlipHelper.getAvailableDtoPaths(((Blip) _eContainer));
  }
  
  public static List<String> getAvailableDtoPaths(final Blip blip) {
    ArrayList<String> results = CollectionLiterals.<String>newArrayList();
    BlipWorkload _workload = null;
    if (blip!=null) {
      _workload=blip.getWorkload();
    }
    BlipDto _source = null;
    if (_workload!=null) {
      _source=_workload.getSource();
    }
    LDto _dtoRef = null;
    if (_source!=null) {
      _dtoRef=_source.getDtoRef();
    }
    final LDto baseDto = _dtoRef;
    boolean _notEquals = (!Objects.equal(baseDto, null));
    if (_notEquals) {
      final LinkedList<LDto> dtoStack = CollectionLiterals.<LDto>newLinkedList(baseDto);
      BlipHelper.recursiveCompleteBlipItem_DtoPath(results, baseDto.getName(), dtoStack);
    }
    return results;
  }
  
  /**
   * TODO: find a more meaningful solution to find unnecessary recursive dto paths
   */
  private static void recursiveCompleteBlipItem_DtoPath(final List<String> results, final String parentName, final LinkedList<LDto> dtoStack) {
    final String proposal = parentName;
    results.add(proposal);
    final LDto actualDto = dtoStack.getLast();
    LDto previousDto = ((LDto) null);
    int _size = dtoStack.size();
    boolean _greaterThan = (_size > 1);
    if (_greaterThan) {
      int _size_1 = dtoStack.size();
      int _minus = (_size_1 - 2);
      previousDto = dtoStack.get(_minus);
    }
    EList<LDtoFeature> _features = actualDto.getFeatures();
    for (final LDtoFeature feature : _features) {
      {
        LDto referencedDto = ((LDto) null);
        LMultiplicity multiplicity = ((LMultiplicity) null);
        String attributeName = "";
        if ((feature instanceof LDtoReferenceImpl)) {
          referencedDto = ((LDtoReferenceImpl)feature).getType();
          attributeName = ((LDtoReferenceImpl)feature).getName();
          multiplicity = ((LDtoReferenceImpl)feature).getMultiplicity();
        }
        if ((feature instanceof LDtoInheritedReferenceImpl)) {
          referencedDto = ((LDtoInheritedReferenceImpl)feature).getType();
          attributeName = ((LDtoInheritedReferenceImpl)feature).getInheritedFeature().getName();
          multiplicity = ((LDtoInheritedReferenceImpl)feature).getInheritedFeature().getMultiplicity();
        }
        boolean _notEquals = (!Objects.equal(referencedDto, null));
        if (_notEquals) {
          StringConcatenation _builder = new StringConcatenation();
          String _name = actualDto.getName();
          _builder.append(_name);
          _builder.append(".");
          String _name_1 = referencedDto.getName();
          _builder.append(_name_1);
          String lastDtoNames = _builder.toString();
          String[] parentNames = parentName.split("\\.");
          StringConcatenation _builder_1 = new StringConcatenation();
          final String[] _converted_parentNames = (String[])parentNames;
          int _size_2 = ((List<String>)Conversions.doWrapArray(_converted_parentNames)).size();
          int _minus_1 = (_size_2 - 1);
          String _get = parentNames[_minus_1];
          _builder_1.append(_get);
          _builder_1.append(".");
          _builder_1.append(attributeName);
          String lastAttributeNames = _builder_1.toString();
          if ((Objects.equal(previousDto, null) || (!previousDto.getName().equals(referencedDto.getName())))) {
            if ((((!Objects.equal(multiplicity, null)) && (!parentName.contains(lastAttributeNames))) && (!BlipHelper.dtoStackNames(dtoStack).contains(lastDtoNames)))) {
              dtoStack.addLast(referencedDto);
              int _size_3 = dtoStack.size();
              boolean _lessThan = (_size_3 < 32);
              if (_lessThan) {
                StringConcatenation _builder_2 = new StringConcatenation();
                _builder_2.append(parentName);
                _builder_2.append(".");
                _builder_2.append(attributeName);
                BlipHelper.recursiveCompleteBlipItem_DtoPath(results, _builder_2.toString(), dtoStack);
              } else {
                System.err.println("BREAKING recursive inspection of dto references due to meaningful depth!");
              }
              dtoStack.removeLast();
            }
          }
        }
      }
    }
  }
  
  private static String dtoStackNames(final LinkedList<LDto> dtoStack) {
    String names = "";
    final Iterator<LDto> iterator = dtoStack.iterator();
    while (iterator.hasNext()) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(names);
      _builder.append(".");
      String _name = iterator.next().getName();
      _builder.append(_name);
      names = _builder.toString();
    }
    return names;
  }
}
