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

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import javax.inject.Inject;
import org.apache.commons.lang.StringEscapeUtils;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoFeature;
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedReference;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.ecview.dsl.extensions.BindableTypeResolver;
import org.eclipse.osbp.ecview.dsl.extensions.OperationExtensions;
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper;
import org.eclipse.osbp.ecview.semantic.uimodel.UiBeanSlot;
import org.eclipse.osbp.ecview.semantic.uimodel.UiLayout;
import org.eclipse.osbp.ecview.semantic.uimodel.UiModel;
import org.eclipse.osbp.ecview.semantic.uimodel.UiView;
import org.eclipse.osbp.ecview.semantic.uimodel.impl.UiViewImpl;
import org.eclipse.osbp.runtime.common.annotations.DomainDescription;
import org.eclipse.osbp.runtime.common.annotations.DomainKey;
import org.eclipse.osbp.runtime.common.annotations.FilterDepth;
import org.eclipse.osbp.runtime.common.annotations.Properties;
import org.eclipse.osbp.utils.common.EntityUtils;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmAnnotationAnnotationValue;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmAnnotationValue;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmIntAnnotationValue;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmStringAnnotationValue;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
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.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;

@SuppressWarnings("all")
public class AutowireUtil {
  public static class Pair {
    public String key;
    
    public String value;
    
    public Pair(final String key, final String value) {
      this.key = key;
      this.value = value;
    }
  }
  
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  @Extension
  private TypeHelper _typeHelper;
  
  @Inject
  private TypeReferences typeReferences;
  
  public String generateId(final UiLayout layout) {
    final BindableTypeResolver resolver = new BindableTypeResolver();
    JvmType resolvedType = resolver.resolveType(layout.getAutoWireSource());
    String viewName = "";
    EObject parent = layout.eContainer();
    while ((!(parent instanceof UiModel))) {
      {
        if ((parent instanceof UiViewImpl)) {
          viewName = ((UiViewImpl) parent).getName();
        }
        parent = parent.eContainer();
      }
    }
    UiModel uimodel = ((UiModel) parent);
    StringConcatenation _builder = new StringConcatenation();
    String _packageName = uimodel.getPackageName();
    _builder.append(_packageName);
    {
      boolean _notEquals = (!Objects.equal(viewName, null));
      if (_notEquals) {
        _builder.append(".");
        _builder.append(viewName);
      }
    }
    {
      boolean _notEquals_1 = (!Objects.equal(resolvedType, null));
      if (_notEquals_1) {
        _builder.append(".");
        String _identifier = resolvedType.getIdentifier();
        _builder.append(_identifier);
      }
    }
    return _builder.toString();
  }
  
  public UiView getUiView(final UiLayout layout) {
    EObject parent = layout.eContainer();
    while ((!(parent instanceof UiViewImpl))) {
      parent = parent.eContainer();
    }
    if ((parent instanceof UiViewImpl)) {
      return ((UiViewImpl) parent);
    }
    return null;
  }
  
  public boolean isAttribute(final JvmType type, final String attribute, final String filterName) {
    LDto dto = EntityUtils.getDto(type);
    boolean _notEquals = (!Objects.equal(dto, null));
    if (_notEquals) {
      final Function1<LDtoAbstractAttribute, Boolean> _function = (LDtoAbstractAttribute it) -> {
        String _name = this.toName(it);
        return Boolean.valueOf(Objects.equal(_name, attribute));
      };
      LDtoAbstractAttribute attr = IterableExtensions.<LDtoAbstractAttribute>findFirst(dto.getAttributes(), _function);
      boolean _notEquals_1 = (!Objects.equal(attr, null));
      if (_notEquals_1) {
        LScalarType _datatype = this.toDatatype(attr);
        LDataType datatype = ((LDataType) _datatype);
        String _name = datatype.getName();
        return Objects.equal(_name, filterName);
      }
    }
    return false;
  }
  
  /**
   * Detects all the existing properties of the jvmtype corresponding attribute, the datatype of the attribute and references.
   */
  public List<AutowireUtil.Pair> toProperties(final JvmDeclaredType type, final String attributeName) {
    final List<AutowireUtil.Pair> result = this.toFieldProperties(type).get(attributeName);
    boolean _notEquals = (!Objects.equal(result, null));
    if (_notEquals) {
      for (final AutowireUtil.Pair prop : result) {
        prop.value = StringEscapeUtils.unescapeHtml(prop.value);
      }
    }
    List<AutowireUtil.Pair> _xifexpression = null;
    boolean _notEquals_1 = (!Objects.equal(result, null));
    if (_notEquals_1) {
      _xifexpression = result;
    } else {
      _xifexpression = CollectionLiterals.<AutowireUtil.Pair>newArrayList();
    }
    return _xifexpression;
  }
  
  /**
   * Detects all the existing properties of the jvmtype corresponding reference and the referenced dto.
   */
  public Map<String, List<AutowireUtil.Pair>> toFieldProperties(final JvmDeclaredType jvmType) {
    final Map<String, List<AutowireUtil.Pair>> propMap = CollectionLiterals.<String, List<AutowireUtil.Pair>>newHashMap();
    final Consumer<JvmField> _function = (JvmField it) -> {
      StringConcatenation _builder = new StringConcatenation();
      String _qualifiedName = jvmType.getQualifiedName();
      _builder.append(_qualifiedName);
      _builder.append(".");
      String _simpleName = it.getSimpleName();
      _builder.append(_simpleName);
      final String attrPropKey = _builder.toString();
      final List<AutowireUtil.Pair> values = CollectionLiterals.<AutowireUtil.Pair>newArrayList();
      propMap.put(attrPropKey, values);
      final Function1<JvmAnnotationReference, Boolean> _function_1 = (JvmAnnotationReference e) -> {
        final boolean result = e.getAnnotation().getIdentifier().equals(Properties.class.getName());
        return Boolean.valueOf(result);
      };
      final Consumer<JvmAnnotationReference> _function_2 = (JvmAnnotationReference it_1) -> {
        final JvmAnnotationReference ref = it_1;
        final Function1<JvmAnnotationValue, JvmAnnotationAnnotationValue> _function_3 = (JvmAnnotationValue it_2) -> {
          return ((JvmAnnotationAnnotationValue) it_2);
        };
        final Consumer<JvmAnnotationAnnotationValue> _function_4 = (JvmAnnotationAnnotationValue av) -> {
          final Consumer<JvmAnnotationReference> _function_5 = (JvmAnnotationReference it_2) -> {
            JvmAnnotationValue _get = it_2.getValues().get(0);
            final JvmStringAnnotationValue keyAn = ((JvmStringAnnotationValue) _get);
            JvmAnnotationValue _get_1 = it_2.getValues().get(1);
            final JvmStringAnnotationValue valueAn = ((JvmStringAnnotationValue) _get_1);
            String _get_2 = keyAn.getValues().get(0);
            String _get_3 = valueAn.getValues().get(0);
            AutowireUtil.Pair _pair = new AutowireUtil.Pair(_get_2, _get_3);
            values.add(_pair);
          };
          av.getValues().forEach(_function_5);
        };
        ListExtensions.<JvmAnnotationValue, JvmAnnotationAnnotationValue>map(ref.getValues(), _function_3).forEach(_function_4);
      };
      IterableExtensions.<JvmAnnotationReference>filter(it.getAnnotations(), _function_1).forEach(_function_2);
    };
    Iterables.<JvmField>filter(jvmType.getAllFeatures(), JvmField.class).forEach(_function);
    return propMap;
  }
  
  /**
   * Returns the depth of the filter for BeanReferenceFields
   */
  public int toFilterDepth(final JvmField field) {
    final Function1<JvmAnnotationReference, Boolean> _function = (JvmAnnotationReference e) -> {
      final boolean result = e.getAnnotation().getIdentifier().equals(FilterDepth.class.getName());
      return Boolean.valueOf(result);
    };
    final JvmAnnotationReference ref = IterableExtensions.<JvmAnnotationReference>findFirst(field.getAnnotations(), _function);
    if ((ref == null)) {
      return 0;
    }
    JvmAnnotationValue _get = ref.getValues().get(0);
    final JvmIntAnnotationValue depthVal = ((JvmIntAnnotationValue) _get);
    return (depthVal.getValues().get(0)).intValue();
  }
  
  /**
   * Detects all the existing properties of the jvmtype corresponding datatype of the attribute.
   */
  public LDataType toDataType(final JvmType type, final String attributeName) {
    LDto dto = EntityUtils.getDto(type);
    boolean _notEquals = (!Objects.equal(dto, null));
    if (_notEquals) {
      final Function1<LDtoAbstractAttribute, Boolean> _function = (LDtoAbstractAttribute it) -> {
        String _name = this.toName(it);
        return Boolean.valueOf(Objects.equal(_name, attributeName));
      };
      LDtoAbstractAttribute attr = IterableExtensions.<LDtoAbstractAttribute>findFirst(dto.getAttributes(), _function);
      boolean _notEquals_1 = (!Objects.equal(attr, null));
      if (_notEquals_1) {
        LScalarType dataType = this.toDatatype(attr);
        if ((dataType instanceof LDataType)) {
          LScalarType _datatype = this.toDatatype(attr);
          return ((LDataType) _datatype);
        }
      }
    }
    return null;
  }
  
  /**
   * Provides the datatype of the corresponding attribute.
   */
  public List<LKeyAndValue> toDataTypeProperties(final JvmType type, final String attributeName) {
    LDataType dataType = this.toDataType(type, attributeName);
    boolean _notEquals = (!Objects.equal(dataType, null));
    if (_notEquals) {
      return dataType.getProperties();
    }
    return CollectionLiterals.<LKeyAndValue>newArrayList();
  }
  
  public String toName(final LDtoFeature feature) {
    if ((feature instanceof LDtoInheritedAttribute)) {
      return ((LDtoInheritedAttribute)feature).getInheritedFeature().getName();
    } else {
      if ((feature instanceof LDtoInheritedReference)) {
        return ((LDtoInheritedReference)feature).getInheritedFeature().getName();
      } else {
        return feature.getName();
      }
    }
  }
  
  public LScalarType toDatatype(final LDtoAbstractAttribute att) {
    if ((att instanceof LDtoInheritedAttribute)) {
      return ((LDtoInheritedAttribute)att).getInheritedFeature().getType();
    } else {
      return att.getType();
    }
  }
  
  public boolean isBlob(final JvmType type, final String attribute) {
    LDto dto = EntityUtils.getDto(type);
    final Function1<LDtoAbstractAttribute, Boolean> _function = (LDtoAbstractAttribute it) -> {
      String _name = it.getName();
      return Boolean.valueOf(Objects.equal(_name, attribute));
    };
    Iterable<LDtoAbstractAttribute> attrs = IterableExtensions.<LDtoAbstractAttribute>filter(dto.getAttributes(), _function);
    for (final LDtoAbstractAttribute attr : attrs) {
      {
        LScalarType _type = attr.getType();
        LDataType datatype = ((LDataType) _type);
        InputOutput.<LDataType>println(datatype);
        return datatype.isAsBlob();
      }
    }
    return false;
  }
  
  public String getEntityName(final UiBeanSlot uiBeanSlot) {
    LEntity _entityFromDto = EntityUtils.getEntityFromDto(uiBeanSlot.getJvmType().getType());
    final LEntity entity = ((LEntity) _entityFromDto);
    String eName = null;
    boolean _equals = Objects.equal(entity, null);
    if (_equals) {
      JvmType _type = uiBeanSlot.getJvmType().getType();
      boolean _equals_1 = Objects.equal(_type, null);
      if (_equals_1) {
        eName = "";
      } else {
        JvmType _type_1 = uiBeanSlot.getJvmType().getType();
        boolean _notEquals = (!Objects.equal(_type_1, null));
        if (_notEquals) {
          eName = "";
        }
      }
    } else {
      eName = entity.getName();
    }
    return eName;
  }
  
  public boolean isClass(final JvmType type) {
    boolean _is = this.typeReferences.is(type, Class.class);
    if (_is) {
      return true;
    }
    return false;
  }
  
  public boolean isByteArray(final JvmType type) {
    boolean _is = this.typeReferences.is(type, byte[].class);
    if (_is) {
      return true;
    }
    return false;
  }
  
  public boolean isAllowed(final JvmType type, final JvmType beanType, final OperationExtensions.OperationInfo info) {
    boolean _isNumberWithDigits = this._typeHelper.isNumberWithDigits(type);
    if (_isNumberWithDigits) {
      return true;
    } else {
      boolean _isNumberWithoutDigits = this._typeHelper.isNumberWithoutDigits(type);
      if (_isNumberWithoutDigits) {
        return true;
      } else {
        boolean _isString = this._typeHelper.isString(type);
        if (_isString) {
          return true;
        } else {
          boolean _isDate = this._typeHelper.isDate(type);
          if (_isDate) {
            return true;
          } else {
            boolean _isByteArray = this.isByteArray(type);
            if (_isByteArray) {
              return true;
            } else {
              boolean _isBoolean = this._typeHelper.isBoolean(type);
              if (_isBoolean) {
                return true;
              } else {
                boolean _isEnum = this._typeHelper.isEnum(type);
                if (_isEnum) {
                  return true;
                } else {
                  boolean _isDomainReference = this._typeHelper.isDomainReference(info);
                  if (_isDomainReference) {
                    boolean _matched = false;
                    if (type instanceof JvmDeclaredType) {
                      _matched=true;
                      if ((this.isAnnotationOf(((JvmDeclaredType) type), DomainKey.class) || 
                        this.isAnnotationOf(((JvmDeclaredType) type), DomainDescription.class))) {
                        return true;
                      }
                    }
                    return false;
                  } else {
                    if (((!Objects.equal(info.getField(), null)) && this._typeHelper.isCollection(info.getField()))) {
                      return true;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    return false;
  }
  
  private boolean isAnnotationOf(final JvmDeclaredType type, final Class<?> clazz) {
    EList<JvmMember> _members = type.getMembers();
    for (final JvmMember member : _members) {
      EList<JvmAnnotationReference> _annotations = member.getAnnotations();
      for (final JvmAnnotationReference annotation : _annotations) {
        boolean _equals = annotation.getAnnotation().getIdentifier().equals(clazz.getCanonicalName());
        if (_equals) {
          return true;
        }
      }
    }
    EList<JvmTypeReference> _superTypes = type.getSuperTypes();
    for (final JvmTypeReference superType : _superTypes) {
      JvmType _type = superType.getType();
      if ((_type instanceof JvmDeclaredType)) {
        JvmType _type_1 = superType.getType();
        return this.isAnnotationOf(((JvmDeclaredType) _type_1), clazz);
      }
    }
    return false;
  }
}
