/**
 * 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.messagedsl.jvmmodel;

import com.google.common.base.CaseFormat;
import java.util.Arrays;
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.osbp.xtext.messagedsl.MessageCategory;
import org.eclipse.osbp.xtext.messagedsl.MessageItem;
import org.eclipse.osbp.xtext.messagedsl.MessageModel;
import org.eclipse.osbp.xtext.messagedsl.MessagePackage;
import org.eclipse.osbp.xtext.messagedsl.MessageParameter;
import org.eclipse.osbp.xtext.messagedsl.MessageText;
import org.eclipse.osbp.xtext.messagedsl.ParameterTypeEnum;
import org.eclipse.osbp.xtext.messagedsl.SeverityEnum;
import org.eclipse.osbp.xtext.messagedsl.common.IMessageCategory;
import org.eclipse.osbp.xtext.messagedsl.common.Message;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable;
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer;
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor;
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor.IPostIndexingInitializing;
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.slf4j.Logger;

/**
 * <p>Infers a JVM model from the source model.</p>
 * 
 * <p>The JVM model should contain all elements that would appear in the Java code
 * which is generated from the source model. Other models link against the JVM model rather than the source model.</p>
 */
@SuppressWarnings("all")
public class MessageDslJvmModelInferrer extends AbstractModelInferrer {
  /**
   * convenience API to build and initialize JVM types and their members.
   */
  @Inject
  @Extension
  private JvmTypesBuilder _jvmTypesBuilder;
  
  /**
   * The dispatch method {@code infer} is called for each instance of the
   * given element's type that is contained in a resource.
   * 
   * @param element
   *            the model to create one or more
   *            {@link JvmDeclaredType declared
   *            types} from.
   * @param acceptor
   *            each created
   *            {@link JvmDeclaredType type}
   *            without a container should be passed to the acceptor in order
   *            get attached to the current resource. The acceptor's
   *            {@link IJvmDeclaredTypeAcceptor#accept(org.eclipse.xtext.common.types.JvmDeclaredType)
   *            accept(..)} method takes the constructed empty type for the
   *            pre-indexing phase. This one is further initialized in the
   *            indexing phase using the closure you pass to the returned
   *            {@link IPostIndexingInitializing#initializeLater(org.eclipse.xtext.xbase.lib.Procedures.Procedure1)
   *            initializeLater(..)}.
   * @param isPreIndexingPhase
   *            whether the method is called in a pre-indexing phase, i.e.
   *            when the global index is not yet fully updated. You must not
   *            rely on linking using the index if isPreIndexingPhase is
   *            <code>true</code>.
   */
  protected void _infer(final MessageModel model, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPreIndexingPhase) {
    final Consumer<MessageCategory> _function = new Consumer<MessageCategory>() {
      @Override
      public void accept(final MessageCategory category) {
        StringConcatenation _builder = new StringConcatenation();
        String _fQMessageClass = MessageDslJvmModelInferrer.getFQMessageClass(category);
        _builder.append(_fQMessageClass);
        final Procedure1<JvmGenericType> _function = new Procedure1<JvmGenericType>() {
          @Override
          public void apply(final JvmGenericType it) {
            EList<JvmTypeReference> _superTypes = it.getSuperTypes();
            JvmTypeReference _typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(IMessageCategory.class);
            MessageDslJvmModelInferrer.this._jvmTypesBuilder.<JvmTypeReference>operator_add(_superTypes, _typeRef);
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("<b>This class was auto generated! Leave it unmodified to avoid unpredictable results!</b><br>");
            _builder.newLine();
            _builder.append("\t\t\t\t");
            String _documentation = MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(category);
            _builder.append(_documentation, "\t\t\t\t");
            _builder.newLineIfNotEmpty();
            MessageDslJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, _builder.toString());
            it.setFinal(true);
            MessageDslJvmModelInferrer.this._jvmTypesBuilder.setFileHeader(it, MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(model.getPckg()));
            final Consumer<MessageItem> _function = new Consumer<MessageItem>() {
              @Override
              public void accept(final MessageItem item) {
                EList<JvmMember> _members = it.getMembers();
                JvmOperation _method = MessageDslJvmModelInferrer.this.toMethod(false, model, category, item, acceptor);
                MessageDslJvmModelInferrer.this._jvmTypesBuilder.<JvmOperation>operator_add(_members, _method);
                EList<JvmMember> _members_1 = it.getMembers();
                JvmOperation _method_1 = MessageDslJvmModelInferrer.this.toMethod(true, model, category, item, acceptor);
                MessageDslJvmModelInferrer.this._jvmTypesBuilder.<JvmOperation>operator_add(_members_1, _method_1);
              }
            };
            category.getItems().forEach(_function);
          }
        };
        acceptor.<JvmGenericType>accept(MessageDslJvmModelInferrer.this._jvmTypesBuilder.toClass(model, _builder.toString()), _function);
      }
    };
    model.getPckg().getCategories().forEach(_function);
  }
  
  /**
   * return the simple generated class name for the message category
   */
  public static String getSimpleMessageClass(final MessageCategory category) {
    StringConcatenation _builder = new StringConcatenation();
    String _name = category.getName();
    _builder.append(_name);
    _builder.append("Message");
    return _builder.toString();
  }
  
  /**
   * return the fully qualified generated class name for the message category
   */
  public static String getFQMessageClass(final MessageCategory category) {
    StringConcatenation _builder = new StringConcatenation();
    EObject _eContainer = category.eContainer();
    String _name = ((MessagePackage) _eContainer).getName();
    _builder.append(_name);
    _builder.append(".");
    String _simpleMessageClass = MessageDslJvmModelInferrer.getSimpleMessageClass(category);
    _builder.append(_simpleMessageClass);
    return _builder.toString();
  }
  
  /**
   * return the fully qualified generated class name for the message item
   */
  public static String getFQMessageClass(final MessageItem item) {
    EObject _eContainer = item.eContainer();
    return MessageDslJvmModelInferrer.getFQMessageClass(((MessageCategory) _eContainer));
  }
  
  /**
   * return the generated method name for the message item
   */
  public static String getMethodName(final MessageItem item) {
    return item.getName();
  }
  
  public JvmOperation toMethod(final boolean withLogger, final MessageModel model, final MessageCategory category, final MessageItem item, final IJvmDeclaredTypeAcceptor acceptor) {
    StringConcatenation _builder = new StringConcatenation();
    String _firstLower = StringExtensions.toFirstLower(item.getName());
    _builder.append(_firstLower);
    final Procedure1<JvmOperation> _function = new Procedure1<JvmOperation>() {
      @Override
      public void apply(final JvmOperation it) {
        final String fqMessageClass = MessageDslJvmModelInferrer.getFQMessageClass(item);
        String docCompiled = ((String) "");
        String _documentation = MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(item);
        if ((_documentation instanceof String)) {
          StringConcatenation _builder = new StringConcatenation();
          _builder.append(docCompiled);
          _builder.newLineIfNotEmpty();
          _builder.append("                ");
          String _documentation_1 = MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(item);
          _builder.append(_documentation_1, "                ");
          _builder.append("<br>");
          _builder.newLineIfNotEmpty();
          docCompiled = _builder.toString();
        }
        boolean _isEmpty = item.getSeverities().isEmpty();
        boolean _not = (!_isEmpty);
        if (_not) {
          StringConcatenation _builder_1 = new StringConcatenation();
          _builder_1.append(docCompiled);
          _builder_1.newLineIfNotEmpty();
          _builder_1.append("                ");
          _builder_1.append("Severity of this message as<ul>");
          _builder_1.newLine();
          docCompiled = _builder_1.toString();
        }
        EList<SeverityEnum> _severities = item.getSeverities();
        for (final SeverityEnum severity : _severities) {
          StringConcatenation _builder_2 = new StringConcatenation();
          _builder_2.append(docCompiled);
          _builder_2.newLineIfNotEmpty();
          _builder_2.append("                ");
          _builder_2.append("<li>");
          _builder_2.append(severity, "                ");
          _builder_2.append("</li>");
          _builder_2.newLineIfNotEmpty();
          docCompiled = _builder_2.toString();
        }
        boolean _isEmpty_1 = item.getSeverities().isEmpty();
        boolean _not_1 = (!_isEmpty_1);
        if (_not_1) {
          StringConcatenation _builder_3 = new StringConcatenation();
          _builder_3.append(docCompiled);
          _builder_3.newLineIfNotEmpty();
          _builder_3.append("                ");
          _builder_3.append("</ul>");
          _builder_3.newLine();
          docCompiled = _builder_3.toString();
        }
        String logger = ((String) "");
        if (withLogger) {
          StringConcatenation _builder_4 = new StringConcatenation();
          _builder_4.append(docCompiled);
          _builder_4.newLineIfNotEmpty();
          _builder_4.append("                ");
          _builder_4.append("@param logger set the slf4j logger used when logging this message");
          _builder_4.newLine();
          docCompiled = _builder_4.toString();
          EList<JvmFormalParameter> _parameters = it.getParameters();
          JvmFormalParameter _parameter = MessageDslJvmModelInferrer.this._jvmTypesBuilder.toParameter(model, "logger", MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(Logger.class));
          MessageDslJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
          logger = "logger,";
        } else {
          StringConcatenation _builder_5 = new StringConcatenation();
          _builder_5.append(docCompiled);
          _builder_5.newLineIfNotEmpty();
          _builder_5.append("                ");
          _builder_5.append("the default logger ");
          _builder_5.append(fqMessageClass, "                ");
          _builder_5.append(" will be used");
          _builder_5.newLineIfNotEmpty();
          docCompiled = _builder_5.toString();
        }
        boolean bodyCompiledHasParam = false;
        StringConcatenation _builder_6 = new StringConcatenation();
        _builder_6.append("return (");
        _builder_6.newLine();
        _builder_6.append("    ");
        _builder_6.append("new Message(");
        _builder_6.append(logger, "    ");
        String bodyCompiled = _builder_6.toString();
        MessageText _logOutput = item.getLogOutput();
        boolean _tripleNotEquals = (_logOutput != null);
        if (_tripleNotEquals) {
          StringConcatenation _builder_7 = new StringConcatenation();
          _builder_7.append(bodyCompiled);
          _builder_7.newLineIfNotEmpty();
          _builder_7.append("                ");
          _builder_7.append("\"");
          String _escapedFormat = MessageDslJvmModelInferrer.this.escapedFormat(item.getLogOutput());
          _builder_7.append(_escapedFormat, "                ");
          _builder_7.append("\"");
          _builder_7.newLineIfNotEmpty();
          _builder_7.append("                ");
          _builder_7.append(", \"\"");
          _builder_7.newLine();
          bodyCompiled = _builder_7.toString();
          bodyCompiledHasParam = true;
        }
        MessageText _showOutput = item.getShowOutput();
        boolean _tripleNotEquals_1 = (_showOutput != null);
        if (_tripleNotEquals_1) {
          StringConcatenation _builder_8 = new StringConcatenation();
          _builder_8.append(bodyCompiled);
          _builder_8.newLineIfNotEmpty();
          _builder_8.append("                ");
          {
            if (bodyCompiledHasParam) {
              _builder_8.append(", ");
            }
          }
          _builder_8.append("\"\"");
          _builder_8.newLineIfNotEmpty();
          _builder_8.append("                ");
          _builder_8.append(", \"");
          String _escapedFormat_1 = MessageDslJvmModelInferrer.this.escapedFormat(item.getShowOutput());
          _builder_8.append(_escapedFormat_1, "                ");
          _builder_8.append("\"");
          _builder_8.newLineIfNotEmpty();
          bodyCompiled = _builder_8.toString();
          bodyCompiledHasParam = true;
        }
        MessageText _allOutput = item.getAllOutput();
        boolean _tripleNotEquals_2 = (_allOutput != null);
        if (_tripleNotEquals_2) {
          StringConcatenation _builder_9 = new StringConcatenation();
          _builder_9.append(bodyCompiled);
          _builder_9.newLineIfNotEmpty();
          _builder_9.append("                ");
          {
            if (bodyCompiledHasParam) {
              _builder_9.append(", ");
            }
          }
          _builder_9.append("\"");
          String _escapedFormat_2 = MessageDslJvmModelInferrer.this.escapedFormat(item.getAllOutput());
          _builder_9.append(_escapedFormat_2, "                ");
          _builder_9.append("\"");
          _builder_9.newLineIfNotEmpty();
          _builder_9.append("                ");
          _builder_9.append(", \"");
          String _escapedFormat_3 = MessageDslJvmModelInferrer.this.escapedFormat(item.getAllOutput());
          _builder_9.append(_escapedFormat_3, "                ");
          _builder_9.append("\"");
          _builder_9.newLineIfNotEmpty();
          bodyCompiled = _builder_9.toString();
          bodyCompiledHasParam = true;
        }
        EList<MessageParameter> _parameters_1 = item.getParameters();
        for (final MessageParameter parameter : _parameters_1) {
          {
            JvmTypeReference typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(String.class);
            ParameterTypeEnum _oftype = parameter.getOftype();
            if (_oftype != null) {
              switch (_oftype) {
                case BOOLEAN:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(boolean.class);
                  break;
                case CLASS:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(Class.class);
                  break;
                case DOUBLE:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(double.class);
                  break;
                case EXCEPTION:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(Exception.class);
                  break;
                case INTEGER:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(int.class);
                  break;
                case OBJECT:
                  typeRef = MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(Object.class);
                  break;
                default:
                  MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(String.class);
                  break;
              }
            } else {
              MessageDslJvmModelInferrer.this._typeReferenceBuilder.typeRef(String.class);
            }
            EList<JvmFormalParameter> _parameters_2 = it.getParameters();
            JvmFormalParameter _parameter_1 = MessageDslJvmModelInferrer.this._jvmTypesBuilder.toParameter(model, parameter.getName(), typeRef);
            MessageDslJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters_2, _parameter_1);
            StringConcatenation _builder_10 = new StringConcatenation();
            _builder_10.append(docCompiled);
            _builder_10.newLineIfNotEmpty();
            _builder_10.append("                ");
            _builder_10.append("@param ");
            String _name = parameter.getName();
            _builder_10.append(_name, "                ");
            _builder_10.append(" ");
            String _documentation_2 = MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(parameter);
            _builder_10.append(_documentation_2, "                ");
            _builder_10.newLineIfNotEmpty();
            docCompiled = _builder_10.toString();
            StringConcatenation _builder_11 = new StringConcatenation();
            _builder_11.append(bodyCompiled);
            _builder_11.newLineIfNotEmpty();
            _builder_11.append("                ");
            _builder_11.append(", \"");
            String _name_1 = parameter.getName();
            _builder_11.append(_name_1, "                ");
            _builder_11.append("\", ");
            String _name_2 = parameter.getName();
            _builder_11.append(_name_2, "                ");
            _builder_11.newLineIfNotEmpty();
            bodyCompiled = _builder_11.toString();
          }
        }
        StringConcatenation _builder_10 = new StringConcatenation();
        _builder_10.append(bodyCompiled);
        _builder_10.append("))");
        _builder_10.newLineIfNotEmpty();
        bodyCompiled = _builder_10.toString();
        EList<SeverityEnum> _severities_1 = item.getSeverities();
        for (final SeverityEnum severity_1 : _severities_1) {
          StringConcatenation _builder_11 = new StringConcatenation();
          _builder_11.append(bodyCompiled);
          _builder_11.newLineIfNotEmpty();
          _builder_11.append("                ");
          _builder_11.append(".");
          String _to = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, severity_1.toString().replace("-", "_"));
          _builder_11.append(_to, "                ");
          _builder_11.append("()");
          _builder_11.newLineIfNotEmpty();
          bodyCompiled = _builder_11.toString();
        }
        StringConcatenation _builder_12 = new StringConcatenation();
        _builder_12.append(bodyCompiled);
        _builder_12.append(";");
        bodyCompiled = _builder_12.toString();
        String _documentation_2 = MessageDslJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(item);
        if ((_documentation_2 instanceof String)) {
          StringConcatenation _builder_13 = new StringConcatenation();
          _builder_13.append(docCompiled);
          _builder_13.newLineIfNotEmpty();
          _builder_13.append("                ");
          _builder_13.append("@return instance of Message, which can be used any further");
          _builder_13.newLine();
          docCompiled = _builder_13.toString();
        }
        it.setStatic(true);
        it.setFinal(true);
        it.setVisibility(JvmVisibility.PUBLIC);
        MessageDslJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, docCompiled.trim());
        final String theBody = bodyCompiled;
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          @Override
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append(theBody);
            it.append(_builder);
          }
        };
        MessageDslJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    return this._jvmTypesBuilder.toMethod(model, _builder.toString(), this._typeReferenceBuilder.typeRef(Message.class), _function);
  }
  
  public String escapedFormat(final MessageText msg) {
    String _text = msg.getText();
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("\\n");
    StringConcatenation _builder_1 = new StringConcatenation();
    _builder_1.append("\\\\n");
    String _replaceAll = _text.replaceAll(_builder.toString(), _builder_1.toString());
    StringConcatenation _builder_2 = new StringConcatenation();
    _builder_2.append("\\t");
    StringConcatenation _builder_3 = new StringConcatenation();
    _builder_3.append("\\\\t");
    return _replaceAll.replaceAll(_builder_2.toString(), _builder_3.toString());
  }
  
  public void infer(final EObject model, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPreIndexingPhase) {
    if (model instanceof MessageModel) {
      _infer((MessageModel)model, acceptor, isPreIndexingPhase);
      return;
    } else if (model != null) {
      _infer(model, acceptor, isPreIndexingPhase);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(model, acceptor, isPreIndexingPhase).toString());
    }
  }
}
