/**
 * 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.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();
        }
        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("                ");
          {
            if (withLogger) {
              _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();
        }
        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 (withLogger) {
              _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();
        }
        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 (withLogger) {
              _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();
        }
        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());
    }
  }
}
