/**
 * 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.utils.entityhelper;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.Date;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.osbp.dsl.entity.xtext.extensions.ModelExtensions;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LEnum;
import org.eclipse.osbp.dsl.semantic.common.types.LKeyAndValue;
import org.eclipse.osbp.dsl.semantic.common.types.LPackage;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper;
import org.eclipse.osbp.ui.api.datamart.IDataMart;
import org.eclipse.xtext.common.types.JvmEnumerationType;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.access.IJvmTypeProvider;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

@SuppressWarnings("all")
public class DataType {
  @Inject
  @Extension
  private TypeHelper typeHelper;
  
  @Inject
  private ModelExtensions entityExtensions;
  
  @Inject
  private IJvmTypeProvider.Factory typeProviderFactory;
  
  public LDataType getLDataType(final LAttribute attributeRef) {
    LScalarType type = attributeRef.getType();
    LDataType lDataType = ((LDataType) null);
    if ((type instanceof LDataType)) {
      lDataType = ((LDataType) type);
    }
    return lDataType;
  }
  
  public JvmType getJvmType(final LAttribute attributeRef) {
    LScalarType type = attributeRef.getType();
    LDataType lDataType = ((LDataType) null);
    JvmType ltype = ((JvmType) null);
    if ((type instanceof LDataType)) {
      lDataType = ((LDataType) type);
      boolean _isDate = lDataType.isDate();
      if (_isDate) {
        final IJvmTypeProvider typeProvider = this.getTypeProvider(attributeRef.eResource().getResourceSet());
        return typeProvider.findTypeByName(Date.class.getName());
      } else {
        boolean _isAsBlob = lDataType.isAsBlob();
        if (_isAsBlob) {
          final IJvmTypeProvider typeProvider_1 = this.getTypeProvider(attributeRef.eResource().getResourceSet());
          return typeProvider_1.findTypeByName("byte[]");
        } else {
          JvmTypeReference jvmTypeReference = lDataType.getJvmTypeReference();
          ltype = jvmTypeReference.getType();
          if ((ltype != null)) {
            return ltype;
          }
        }
      }
    } else {
      if ((type instanceof LEnum)) {
        EObject _eContainer = ((LEnum)type).eContainer();
        LPackage pkg = ((LPackage) _eContainer);
        final IJvmTypeProvider typeProvider_2 = this.getTypeProvider(attributeRef.eResource().getResourceSet());
        String _name = pkg.getName();
        String _plus = (_name + ".");
        String _name_1 = ((LEnum)type).getName();
        String _plus_1 = (_plus + _name_1);
        return typeProvider_2.findTypeByName(_plus_1);
      }
    }
    JvmTypeReference typeJvm = null;
    if ((attributeRef instanceof LEntityAttribute)) {
      typeJvm = this.entityExtensions.toTypeReference(attributeRef);
    } else {
      typeJvm = this.entityExtensions.toTypeReference(attributeRef);
    }
    JvmType typeJvmType = typeJvm.getType();
    return typeJvmType;
  }
  
  public IJvmTypeProvider getTypeProvider(final ResourceSet rs) {
    return this.typeProviderFactory.findOrCreateTypeProvider(rs);
  }
  
  public IDataMart.EType getBasicType(final String typeIdentifier) {
    if ((typeIdentifier != null)) {
      String identifier = typeIdentifier;
      boolean _startsWith = typeIdentifier.startsWith("java.lang.");
      if (_startsWith) {
        identifier = typeIdentifier.substring("java.lang.".length()).toLowerCase();
      }
      if (identifier != null) {
        switch (identifier) {
          case "boolean":
            return IDataMart.EType.BOOLEAN;
          case "byte":
            return IDataMart.EType.BYTE;
          case "short":
            return IDataMart.EType.SHORT;
          case "int":
            return IDataMart.EType.INTEGER;
          case "integer":
            return IDataMart.EType.INTEGER;
          case "long":
            return IDataMart.EType.LONG;
          case "double":
            return IDataMart.EType.DOUBLE;
          case "float":
            return IDataMart.EType.FLOAT;
          case "BigDecimal":
            return IDataMart.EType.DOUBLE;
          case "java.math.BigDecimal":
            return IDataMart.EType.DOUBLE;
          case "string":
            return IDataMart.EType.STRING;
          case "java.util.Date":
            return IDataMart.EType.DATE;
        }
      }
    }
    return IDataMart.EType.NONE;
  }
  
  public IDataMart.EType getBasicType(final JvmType type) {
    boolean _isBoolean = this.typeHelper.isBoolean(type);
    if (_isBoolean) {
      return IDataMart.EType.BOOLEAN;
    } else {
      boolean _isNumberWithDigits = this.typeHelper.isNumberWithDigits(type);
      if (_isNumberWithDigits) {
        final IDataMart.EType retcode = this.getBasicType(type.getIdentifier());
        if ((retcode != IDataMart.EType.NONE)) {
          return retcode;
        }
        return IDataMart.EType.DOUBLE;
      } else {
        boolean _isNumberWithoutDigits = this.typeHelper.isNumberWithoutDigits(type);
        if (_isNumberWithoutDigits) {
          final IDataMart.EType retcode_1 = this.getBasicType(type.getIdentifier());
          if ((retcode_1 != IDataMart.EType.NONE)) {
            return retcode_1;
          }
          return IDataMart.EType.INTEGER;
        } else {
          boolean _isString = this.typeHelper.isString(type);
          if (_isString) {
            return IDataMart.EType.STRING;
          } else {
            boolean _isDate = this.typeHelper.isDate(type);
            if (_isDate) {
              return IDataMart.EType.DATE;
            } else {
              if ((type instanceof JvmEnumerationType)) {
                return IDataMart.EType.LENUM;
              }
            }
          }
        }
      }
    }
    return this.getBasicType(type.getIdentifier());
  }
  
  public IDataMart.EType getBasicType(final LAttribute attribute) {
    LDataType lDataType = this.getLDataType(attribute);
    if ((lDataType != null)) {
      boolean _isDate = lDataType.isDate();
      if (_isDate) {
        return IDataMart.EType.DATE;
      }
      boolean _isNullOrEmpty = IterableExtensions.isNullOrEmpty(lDataType.getProperties());
      boolean _not = (!_isNullOrEmpty);
      if (_not) {
        final Function1<LKeyAndValue, Boolean> _function = (LKeyAndValue it) -> {
          return Boolean.valueOf(it.getKey().toLowerCase().equals("blob"));
        };
        boolean _exists = IterableExtensions.<LKeyAndValue>exists(lDataType.getProperties(), _function);
        if (_exists) {
          return IDataMart.EType.BLOPMAPPING;
        }
        final Function1<LKeyAndValue, Boolean> _function_1 = (LKeyAndValue it) -> {
          return Boolean.valueOf(it.getValue().toLowerCase().equals("richtextarea"));
        };
        boolean _exists_1 = IterableExtensions.<LKeyAndValue>exists(lDataType.getProperties(), _function_1);
        if (_exists_1) {
          return IDataMart.EType.RICHTEXTAREA;
        }
      }
      boolean _isNullOrEmpty_1 = IterableExtensions.isNullOrEmpty(attribute.getProperties());
      boolean _not_1 = (!_isNullOrEmpty_1);
      if (_not_1) {
        final Function1<LKeyAndValue, Boolean> _function_2 = (LKeyAndValue it) -> {
          return Boolean.valueOf(it.getKey().toLowerCase().equals("blob"));
        };
        boolean _exists_2 = IterableExtensions.<LKeyAndValue>exists(attribute.getProperties(), _function_2);
        if (_exists_2) {
          return IDataMart.EType.BLOPMAPPING;
        }
        final Function1<LKeyAndValue, Boolean> _function_3 = (LKeyAndValue it) -> {
          return Boolean.valueOf(it.getValue().toLowerCase().equals("richtextarea"));
        };
        boolean _exists_3 = IterableExtensions.<LKeyAndValue>exists(attribute.getProperties(), _function_3);
        if (_exists_3) {
          return IDataMart.EType.RICHTEXTAREA;
        }
      }
      boolean _equalsIgnoreCase = "blobMapping".equalsIgnoreCase(lDataType.getName());
      if (_equalsIgnoreCase) {
        return IDataMart.EType.BLOPMAPPING;
      }
    }
    return this.getBasicType(this.getJvmType(attribute));
  }
  
  public IDataMart.EType getBasicType(final Class<?> typeClass) {
    return this.getBasicType(typeClass.getCanonicalName());
  }
  
  public boolean canBeCastFrom(final LEntityAttribute targetAttribute, final Class<?> sourceClass) {
    return this.canBeCastFrom(targetAttribute, this.getBasicType(sourceClass));
  }
  
  public boolean canBeCastFrom(final LEntityAttribute targetAttribute, final IDataMart.EType sourceType) {
    IDataMart.EType targetType = this.getBasicType(targetAttribute);
    if (targetType != null) {
      switch (targetType) {
        case BOOLEAN:
          return Objects.equal(sourceType, IDataMart.EType.BOOLEAN);
        case BYTE:
          return Objects.equal(sourceType, IDataMart.EType.BYTE);
        case DATE:
          return Objects.equal(sourceType, IDataMart.EType.DATE);
        case FLOAT:
          return ((((Objects.equal(sourceType, IDataMart.EType.FLOAT) || Objects.equal(sourceType, IDataMart.EType.LONG)) || Objects.equal(sourceType, IDataMart.EType.INTEGER)) || 
            Objects.equal(sourceType, IDataMart.EType.SHORT)) || Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case DOUBLE:
          return (((((Objects.equal(sourceType, IDataMart.EType.FLOAT) || Objects.equal(sourceType, IDataMart.EType.DOUBLE)) || Objects.equal(sourceType, IDataMart.EType.LONG)) || 
            Objects.equal(sourceType, IDataMart.EType.INTEGER)) || Objects.equal(sourceType, IDataMart.EType.SHORT)) || Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case SHORT:
          return (Objects.equal(sourceType, IDataMart.EType.SHORT) || Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case INTEGER:
          return ((Objects.equal(sourceType, IDataMart.EType.INTEGER) || Objects.equal(sourceType, IDataMart.EType.SHORT)) || 
            Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case LONG:
          return (((Objects.equal(sourceType, IDataMart.EType.LONG) || Objects.equal(sourceType, IDataMart.EType.INTEGER)) || Objects.equal(sourceType, IDataMart.EType.SHORT)) || 
            Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case STRING:
          return true;
        case TIME:
          return Objects.equal(sourceType, IDataMart.EType.TIME);
        case LENUM:
          return (Objects.equal(sourceType, IDataMart.EType.INTEGER) || Objects.equal(sourceType, IDataMart.EType.BOOLEAN));
        case NONE:
          return false;
        default:
          break;
      }
    }
    return false;
  }
}
