/**
 * 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.table.generator;

import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.inject.Inject;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LClass;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LPackage;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.dto.LDto;
import org.eclipse.osbp.dsl.semantic.dto.LDtoAbstractAttribute;
import org.eclipse.osbp.dsl.semantic.dto.LDtoInheritedAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LBean;
import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute;
import org.eclipse.osbp.ecview.dsl.extensions.TypeHelper;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridProperty;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceFactory;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropPriceStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropQuantityStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleFactory;
import org.eclipse.osbp.infogrid.model.gridsource.util.Util;
import org.eclipse.osbp.xtext.table.Table;
import org.eclipse.osbp.xtext.table.TableDtoDatasource;
import org.eclipse.osbp.xtext.table.TableGrid;
import org.eclipse.osbp.xtext.table.TableModel;
import org.eclipse.osbp.xtext.table.TableOption;
import org.eclipse.osbp.xtext.table.TablePackage;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;

/**
 * Generates code from your model files on save.
 * 
 * see http://www.eclipse.org/Xtext/documentation.html#TutorialCodeGeneration
 */
@SuppressWarnings("all")
public class TableGridSourceGenerator implements IGenerator {
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  @Extension
  private TypeHelper _typeHelper;
  
  @Override
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
    this.toBinary(resource, fsa);
  }
  
  public void toBinary(final Resource input, final IFileSystemAccess fsa) {
    EObject _get = input.getContents().get(0);
    final TableModel lModel = ((TableModel) _get);
    final Consumer<TablePackage> _function = (TablePackage it) -> {
      final String packageName = it.getName();
      final Consumer<Table> _function_1 = (Table it_1) -> {
        final String tableName = it_1.getName();
        TableOption _tabletype = it_1.getTabletype();
        if ((_tabletype instanceof TableGrid)) {
          TableOption _tabletype_1 = it_1.getTabletype();
          this.generateXMI(((TableGrid) _tabletype_1), packageName, tableName, fsa);
        }
      };
      it.getTables().forEach(_function_1);
    };
    lModel.getPackages().forEach(_function);
  }
  
  public void generateXMI(final TableGrid grid, final String packageName, final String tableName, final IFileSystemAccess fsa) {
    try {
      final XMLResource outputRes = new XMLResourceImpl();
      final TableDtoDatasource ds = grid.getSource();
      ds.setId((((packageName + ".") + tableName) + "Grid"));
      StringConcatenation _builder = new StringConcatenation();
      EObject _eContainer = ds.getDtoSource().eContainer();
      String _name = ((LPackage) _eContainer).getName();
      _builder.append(_name);
      _builder.append(".");
      String _name_1 = ds.getDtoSource().getName();
      _builder.append(_name_1);
      ds.setRootTypeFQN(_builder.toString());
      if (((ds.getProperties() != null) && (((Object[])Conversions.unwrapArray(ds.getProperties(), Object.class)).length > 0))) {
        EList<CxGridProperty> _properties = ds.getProperties();
        for (final CxGridProperty prop : _properties) {
          {
            prop.setDotPath(Util.calcDotPath(prop));
            prop.setSourceFQN(this._iQualifiedNameProvider.getFullyQualifiedName(prop.getPath().getField().eContainer()).toString());
            this.prepare(prop.getStyle());
          }
        }
      } else {
        HashMap<String, String> attributesMap = CollectionLiterals.<String, String>newHashMap();
        HashMap<String, LScalarType> attributesTypeMap = CollectionLiterals.<String, LScalarType>newHashMap();
        HashMap<String, String> attributesSourceMap = CollectionLiterals.<String, String>newHashMap();
        String sourceFQN = this._iQualifiedNameProvider.getFullyQualifiedName(ds.getDtoSource()).toString();
        List<LDtoAbstractAttribute> _attributes = ds.getDtoSource().getAttributes();
        for (final LDtoAbstractAttribute attr : _attributes) {
          boolean _allowedAttribute = this.allowedAttribute(ds, attr);
          if (_allowedAttribute) {
            this.fillAttributes(attr, sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap);
          }
        }
        LDto _superType = ds.getDtoSource().getSuperType();
        boolean _tripleNotEquals = (_superType != null);
        if (_tripleNotEquals) {
          sourceFQN = this._iQualifiedNameProvider.getFullyQualifiedName(ds.getDtoSource().getSuperType()).toString();
          List<LDtoAbstractAttribute> _attributes_1 = ds.getDtoSource().getSuperType().getAttributes();
          for (final LDtoAbstractAttribute attr_1 : _attributes_1) {
            boolean _allowedAttribute_1 = this.allowedAttribute(ds, attr_1);
            if (_allowedAttribute_1) {
              this.fillAttributes(attr_1, sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap);
            }
          }
        }
        Set<String> _keySet = attributesMap.keySet();
        for (final String attrKey : _keySet) {
          {
            CxGridProperty prop_1 = CxGridSourceFactory.eINSTANCE.createCxGridProperty();
            prop_1.setDotPath(attributesMap.get(attrKey));
            prop_1.setStyle(this.getPropStyle(attributesTypeMap.get(attrKey)));
            sourceFQN = attributesSourceMap.get(attrKey);
            if ((sourceFQN == null)) {
              sourceFQN = ds.getRootTypeFQN();
            }
            prop_1.setSourceFQN(sourceFQN);
            prop_1.setEditable(true);
            ds.getProperties().add(prop_1);
          }
        }
      }
      final TableDtoDatasource copy = EcoreUtil.<TableDtoDatasource>copy(ds);
      EList<EObject> _contents = outputRes.getContents();
      _contents.add(copy);
      final Writer writer = new StringWriter();
      outputRes.save(writer, null);
      String _id = ds.getId();
      String _plus = (_id + ".gridsource_xmi");
      fsa.generateFile(_plus, "xmi", writer.toString());
    } catch (Throwable _e) {
      throw Exceptions.sneakyThrow(_e);
    }
  }
  
  protected boolean allowedAttribute(final TableDtoDatasource ds, final LDtoAbstractAttribute attr) {
    boolean _xblockexpression = false;
    {
      boolean allowedAttr = true;
      LAttribute attribute = attr;
      if ((attr instanceof LDtoInheritedAttribute)) {
        attribute = ((LDtoInheritedAttribute) attr).getInheritedFeature();
      }
      LType wrappedType = ds.getDtoSource().getWrappedType();
      if ((wrappedType instanceof LClass)) {
        allowedAttr = ((LClass) wrappedType).isNormalAttribute(attribute);
      }
      _xblockexpression = allowedAttr;
    }
    return _xblockexpression;
  }
  
  public CxGridPropStyle getPropStyle(final LScalarType type) {
    if ((type instanceof LDataType)) {
      boolean _isDate = ((LDataType)type).isDate();
      if (_isDate) {
        return CxGridStyleFactory.eINSTANCE.createCxGridPropDateStyle();
      } else {
        boolean _isAsBlob = ((LDataType)type).isAsBlob();
        if (_isAsBlob) {
          return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle();
        } else {
          JvmTypeReference _jvmTypeReference = ((LDataType) type).getJvmTypeReference();
          JvmType _type = null;
          if (_jvmTypeReference!=null) {
            _type=_jvmTypeReference.getType();
          }
          JvmType jvmType = _type;
          if ((jvmType != null)) {
            boolean _isString = this._typeHelper.isString(jvmType);
            if (_isString) {
              return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle();
            } else {
              boolean _isBoolean = this._typeHelper.isBoolean(jvmType);
              if (_isBoolean) {
                return CxGridStyleFactory.eINSTANCE.createCxGridPropBooleanStyle();
              } else {
                boolean _isDate_1 = this._typeHelper.isDate(jvmType);
                if (_isDate_1) {
                  return CxGridStyleFactory.eINSTANCE.createCxGridPropDateStyle();
                } else {
                  boolean _isNumber = this._typeHelper.isNumber(jvmType);
                  if (_isNumber) {
                    return CxGridStyleFactory.eINSTANCE.createCxGridPropNumberStyle();
                  }
                }
              }
            }
          }
        }
      }
    }
    return CxGridStyleFactory.eINSTANCE.createCxGridPropTextStyle();
  }
  
  public void fillAttributes(final LDtoAbstractAttribute attr, final String sourceFQN, final HashMap<String, String> attributesMap, final HashMap<String, LScalarType> attributesTypeMap, final HashMap<String, String> attributesSourceMap) {
    LAttribute attribute = attr;
    if ((attr instanceof LDtoInheritedAttribute)) {
      attribute = ((LDtoInheritedAttribute) attr).getInheritedFeature();
    }
    LScalarType _type = attribute.getType();
    LScalarType type = ((LScalarType) _type);
    this.recurseAttributesMap(sourceFQN, type, attribute, attributesMap, attributesTypeMap, attributesSourceMap);
  }
  
  protected void _prepare(final CxGridPropStyle style) {
  }
  
  protected void _prepare(final CxGridPropPriceStyle style) {
    style.setValuePropertyDotPath(Util.calcDotPath(style.getValuePropertyPath()));
    style.setCurrencyPropertyDotPath(Util.calcDotPath(style.getCurrencyPropertyPath()));
  }
  
  protected void _prepare(final CxGridPropQuantityStyle style) {
    style.setValuePropertyDotPath(Util.calcDotPath(style.getValuePropertyPath()));
    style.setUomPropertyDotPath(Util.calcDotPath(style.getUomPropertyPath()));
  }
  
  public void recurseAttributesMap(final String sourceFQN, final LScalarType type, final LAttribute attribute, final Map<String, String> attributesMap, final HashMap<String, LScalarType> attributesTypeMap, final HashMap<String, String> attributesSourceMap) {
    if (((type != null) && (type instanceof LBean))) {
      LBean bean = ((LBean) type);
      List<LBeanAttribute> _allAttributes = bean.getAllAttributes();
      for (final LBeanAttribute attr : _allAttributes) {
        LScalarType _type = attr.getType();
        if ((_type instanceof LBean)) {
          this.recurseAttributesMap(sourceFQN, attr.getType(), attribute, attributesMap, attributesTypeMap, attributesSourceMap);
        } else {
          this.fillAttributeMaps(attr, sourceFQN, attribute.getName(), attributesMap, attributesTypeMap, attributesSourceMap);
        }
      }
    } else {
      this.fillAttributeMaps(attribute, sourceFQN, attributesMap, attributesTypeMap, attributesSourceMap);
    }
  }
  
  public void fillAttributeMaps(final LAttribute attr, final String sourceFQN, final Map<String, String> attributesMap, final HashMap<String, LScalarType> attributesTypeMap, final HashMap<String, String> attributesSourceMap) {
    this.fillAttributeMaps(attr, sourceFQN, null, attributesMap, attributesTypeMap, attributesSourceMap);
  }
  
  public void fillAttributeMaps(final LAttribute attr, final String sourceFQN, final String attributeBeanName, final Map<String, String> attributesMap, final HashMap<String, LScalarType> attributesTypeMap, final HashMap<String, String> attributesSourceMap) {
    String attrName = attr.getName();
    if ((attributeBeanName != null)) {
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(attributeBeanName);
      _builder.append(".");
      _builder.append(attrName);
      attrName = _builder.toString();
    }
    attributesMap.put(attr.getName(), attrName);
    attributesTypeMap.put(attr.getName(), attr.getType());
    attributesSourceMap.put(attr.getName(), sourceFQN);
  }
  
  public void prepare(final CxGridPropStyle style) {
    if (style instanceof CxGridPropPriceStyle) {
      _prepare((CxGridPropPriceStyle)style);
      return;
    } else if (style instanceof CxGridPropQuantityStyle) {
      _prepare((CxGridPropQuantityStyle)style);
      return;
    } else if (style != null) {
      _prepare(style);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(style).toString());
    }
  }
}
