/**
 * Copyright (c) 2020 CEA LIST
 * 
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse 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:
 *   Abhishek Djeachandrane - Initial API and implementation
 */
package org.eclipse.papyrus.aiml.gen.keras;

import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.papyrus.aiml.gen.keras.GenCheck;
import org.eclipse.papyrus.aiml.gen.keras.ModelOps;
import org.eclipse.papyrus.aiml.gen.keras.ModuleInfo;
import org.eclipse.papyrus.aiml.gen.keras.ModuleInfoAttributes;
import org.eclipse.papyrus.aiml.gen.keras.RecurrentLayerOps;
import org.eclipse.papyrus.aiml.profile.AIML.Convolution_layers.Convolution_layers;
import org.eclipse.papyrus.aiml.profile.AIML.Linear_layers.Linear;
import org.eclipse.papyrus.aiml.profile.AIML.Linear_layers.Linear_layers;
import org.eclipse.papyrus.aiml.profile.AIML.Module.Model;
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.GRU;
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.LSTM;
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.Recurrent_layers;
import org.eclipse.papyrus.aiml.profile.AIML.Tensor.Tensor;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.util.UMLUtil;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;

@SuppressWarnings("all")
public class GenKeras {
  public static CharSequence genKeras(final org.eclipse.uml2.uml.Class clazz) {
    final Model module = UMLUtil.<Model>getStereotypeApplication(clazz, Model.class);
    if ((module != null)) {
      return GenKeras.genModule(module);
    } else {
      return "";
    }
  }
  
  /**
   * Generate a model with different elements necessary for the compilation
   */
  public static CharSequence genModule(final Model module) {
    StringConcatenation _builder = new StringConcatenation();
    CharSequence _genDefaultTemplate = GenKeras.genDefaultTemplate(module);
    _builder.append(_genDefaultTemplate);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    CharSequence _genModuleInit = GenKeras.genModuleInit(module);
    _builder.append(_genModuleInit);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("\t");
    CharSequence _genModuleCall = GenKeras.genModuleCall(module);
    _builder.append(_genModuleCall, "\t");
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    CharSequence _genModuleCompilation = GenKeras.genModuleCompilation(module);
    _builder.append(_genModuleCompilation);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    _builder.newLine();
    return _builder;
  }
  
  /**
   * Generate the model instance and compilation
   */
  public static CharSequence genModuleCompilation(final Model module) {
    StringConcatenation _builder = new StringConcatenation();
    String _firstLower = StringExtensions.toFirstLower(module.getBase_Class().getName());
    _builder.append(_firstLower);
    _builder.append(" = ");
    String _name = module.getBase_Class().getName();
    _builder.append(_name);
    _builder.append("()");
    _builder.newLineIfNotEmpty();
    _builder.append("\t\t");
    ModuleInfoAttributes study = ModelOps.modelAttributesToCollectProperly(module);
    _builder.newLineIfNotEmpty();
    List<String> _list = IterableExtensions.<String>toList(study.attributesName);
    _builder.append(_list);
    _builder.newLineIfNotEmpty();
    List<Object> _list_1 = IterableExtensions.<Object>toList(study.attributesValue);
    _builder.append(_list_1);
    _builder.newLineIfNotEmpty();
    List<String> _list_2 = IterableExtensions.<String>toList(study.attributesType);
    _builder.append(_list_2);
    _builder.newLineIfNotEmpty();
    {
      List<Object> _list_3 = IterableExtensions.<Object>toList(study.attributesValue);
      for(final Object n : _list_3) {
        _builder.newLine();
      }
    }
    String study2 = ModelOps.modelAttributesToDisplayForCompilationProperly(module);
    _builder.newLineIfNotEmpty();
    _builder.append(study2);
    _builder.newLineIfNotEmpty();
    return _builder;
  }
  
  /**
   * Generate the basic template with importation in the head of the code
   */
  public static CharSequence genDefaultTemplate(final Model module) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("# generated by Papyrus from module ");
    Class<? extends org.eclipse.uml2.uml.Class> _class = module.getBase_Class().getClass();
    _builder.append(_class);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    _builder.append("import tensorflow as tf");
    _builder.newLine();
    _builder.append("from tensorflow import keras");
    _builder.newLine();
    _builder.append("inputs=[(1,2),(3,4)]");
    _builder.newLine();
    return _builder;
  }
  
  /**
   * Generate layer instance through modeling
   */
  public static CharSequence genModuleInit(final Model module) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("class ");
    String _name = module.getBase_Class().getName();
    _builder.append(_name);
    _builder.append("(tf.keras.Model):");
    _builder.newLineIfNotEmpty();
    _builder.append("\t");
    _builder.append("def __init__(self):");
    _builder.newLine();
    _builder.append("\t\t");
    _builder.append("super(MyModel, self).__init__()");
    _builder.newLine();
    _builder.append("\t\t");
    _builder.newLine();
    {
      EList<Property> _ownedAttributes = module.getBase_Class().getOwnedAttributes();
      for(final Property layer : _ownedAttributes) {
        _builder.append("\t\t");
        final Type type = layer.getType();
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t");
        final Model layerSt = UMLUtil.<Model>getStereotypeApplication(type, Model.class);
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t");
        CharSequence _genLayer = GenKeras.genLayer(layerSt);
        _builder.append(_genLayer, "\t\t");
        _builder.newLineIfNotEmpty();
      }
    }
    {
      EList<Connector> _ownedConnectors = module.getBase_Class().getOwnedConnectors();
      for(final Connector connector : _ownedConnectors) {
      }
    }
    return _builder;
  }
  
  /**
   * Generate the code which consist to determine the data flow between layers
   * @param l the model ...
   */
  public static CharSequence genModuleCall(final Model module) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("def call(self, inputs):");
    _builder.newLine();
    _builder.newLine();
    int nbr_lay = GenCheck.findNbrOfLayer(module);
    _builder.newLineIfNotEmpty();
    Object unsortedInformationFlowList = ModelOps.genInputOutputLayerArrayWithFlow(Integer.valueOf(nbr_lay), module);
    _builder.newLineIfNotEmpty();
    _builder.newLine();
    {
      if ((unsortedInformationFlowList instanceof ModuleInfo)) {
        ArrayList<String> sortedInformationFlowList = ModelOps.genFlowOrder(Integer.valueOf(nbr_lay), ((ModuleInfo)unsortedInformationFlowList));
        _builder.newLineIfNotEmpty();
        {
          List<String> _list = IterableExtensions.<String>toList(sortedInformationFlowList);
          for(final String layer : _list) {
            _builder.append("\t");
            int _indexOf = IterableExtensions.<String>toList(sortedInformationFlowList).indexOf(layer);
            int inputs = (_indexOf - 1);
            _builder.newLineIfNotEmpty();
            {
              if ((inputs < 0)) {
                _builder.append("\t");
                _builder.append("x");
                int _indexOf_1 = IterableExtensions.<String>toList(sortedInformationFlowList).indexOf(layer);
                _builder.append(_indexOf_1, "\t");
                _builder.append(" = self.");
                _builder.append(layer, "\t");
                _builder.append("(input)");
                _builder.newLineIfNotEmpty();
              } else {
                if (((inputs >= 0) && (inputs < (((Object[])Conversions.unwrapArray(sortedInformationFlowList, Object.class)).length - 2)))) {
                  _builder.append("\t");
                  _builder.append("x");
                  int _indexOf_2 = IterableExtensions.<String>toList(sortedInformationFlowList).indexOf(layer);
                  _builder.append(_indexOf_2, "\t");
                  _builder.append(" = self.");
                  _builder.append(layer, "\t");
                  _builder.append("(x");
                  _builder.append(inputs, "\t");
                  _builder.append(")");
                  _builder.newLineIfNotEmpty();
                } else {
                  final ArrayList<String> _converted_sortedInformationFlowList = (ArrayList<String>)sortedInformationFlowList;
                  int _length = ((Object[])Conversions.unwrapArray(_converted_sortedInformationFlowList, Object.class)).length;
                  int _minus = (_length - 2);
                  boolean _equals = (inputs == _minus);
                  if (_equals) {
                    _builder.append("\t");
                    _builder.append("output = self.");
                    _builder.append(layer, "\t");
                    _builder.append("(x");
                    _builder.append(inputs, "\t");
                    _builder.append(")");
                    _builder.newLineIfNotEmpty();
                  }
                }
              }
            }
          }
        }
      }
    }
    _builder.append("\t");
    _builder.append("return output\t\t");
    _builder.newLine();
    return _builder;
  }
  
  /**
   * Generate each layer according to the model
   */
  public static CharSequence genLayer(final Model layer) {
    CharSequence _xifexpression = null;
    if ((layer instanceof Convolution_layers)) {
      _xifexpression = GenKeras.genConvolutionLayer(((Convolution_layers) layer));
    } else {
      CharSequence _xifexpression_1 = null;
      if ((layer instanceof Recurrent_layers)) {
        _xifexpression_1 = GenKeras.genRecurrentLayer(((Recurrent_layers) layer));
      } else {
        CharSequence _xifexpression_2 = null;
        if ((layer instanceof Linear_layers)) {
          _xifexpression_2 = GenKeras.genLinearLayer(((Linear_layers) layer));
        }
        _xifexpression_1 = _xifexpression_2;
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  /**
   * Generate each convolution layer according to the model
   */
  public static CharSequence genConvolutionLayer(final Convolution_layers convolutionLayer) {
    StringConcatenation _builder = new StringConcatenation();
    return _builder;
  }
  
  /**
   * Generate each linear layer according to the model
   */
  public static CharSequence genLinearLayer(final Linear_layers linearLayer) {
    CharSequence _xifexpression = null;
    if ((linearLayer instanceof Linear)) {
      _xifexpression = GenKeras.genDense(((Linear) linearLayer));
    }
    return _xifexpression;
  }
  
  /**
   * Generate each recurrent layer according to the model
   */
  public static CharSequence genRecurrentLayer(final Recurrent_layers recurrentLayer) {
    CharSequence _xifexpression = null;
    if ((recurrentLayer instanceof LSTM)) {
      _xifexpression = GenKeras.genLstm(((LSTM) recurrentLayer));
    } else {
      CharSequence _xifexpression_1 = null;
      if ((recurrentLayer instanceof GRU)) {
        _xifexpression_1 = GenKeras.genGru(((GRU) recurrentLayer));
      }
      _xifexpression = _xifexpression_1;
    }
    return _xifexpression;
  }
  
  /**
   * Generate each dense layer according to the model
   */
  public static CharSequence genDense(final Linear denseLayer) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("self.");
    String _name = denseLayer.getBase_Class().getName();
    _builder.append(_name);
    _builder.append("=tf.keras.layers.Dense(");
    int _in_features = denseLayer.getIn_features();
    _builder.append(_in_features);
    _builder.append(")");
    _builder.newLineIfNotEmpty();
    return _builder;
  }
  
  /**
   * Generate each LSTM layer according to the model
   */
  public static CharSequence genLstm(final LSTM lstmLayer) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("\t\t\t\t\t\t\t\t\t\t\t\t");
    String tt = RecurrentLayerOps.lstmAttributesToDisplay(lstmLayer);
    _builder.newLineIfNotEmpty();
    _builder.append(tt);
    _builder.newLineIfNotEmpty();
    return _builder;
  }
  
  /**
   * Generate each GRU layer according to the model
   */
  public static CharSequence genGru(final GRU gruLayer) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("\t\t\t\t");
    String tt = RecurrentLayerOps.lstmAttributesToDisplay(gruLayer);
    _builder.newLineIfNotEmpty();
    _builder.append(tt);
    _builder.newLineIfNotEmpty();
    return _builder;
  }
  
  /**
   * Generate each tensor according to the model
   */
  public static CharSequence genTensor(final Tensor tensor) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("tensor ...");
    _builder.newLine();
    return _builder;
  }
}
