/**
 * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
 * 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:
 * 		Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
 */
package org.eclipse.etrice.generator.generic;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import javax.inject.Inject;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.etrice.core.genmodel.etricegen.AbstractInstance;
import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance;
import org.eclipse.etrice.core.genmodel.etricegen.PortInstance;
import org.eclipse.etrice.core.genmodel.etricegen.SAPInstance;
import org.eclipse.etrice.core.genmodel.etricegen.ServiceImplInstance;
import org.eclipse.etrice.core.genmodel.etricegen.StructureInstance;
import org.eclipse.etrice.core.room.ActorClass;
import org.eclipse.etrice.core.room.ExternalPort;
import org.eclipse.etrice.core.room.GeneralProtocolClass;
import org.eclipse.etrice.core.room.Message;
import org.eclipse.etrice.core.room.MessageHandler;
import org.eclipse.etrice.core.room.Port;
import org.eclipse.etrice.core.room.PortClass;
import org.eclipse.etrice.core.room.ProtocolClass;
import org.eclipse.etrice.core.room.RefableType;
import org.eclipse.etrice.core.room.RoomClass;
import org.eclipse.etrice.core.room.RoomModel;
import org.eclipse.etrice.core.room.SAP;
import org.eclipse.etrice.core.room.SPP;
import org.eclipse.etrice.core.room.ServiceImplementation;
import org.eclipse.etrice.core.room.StandardOperation;
import org.eclipse.etrice.core.room.VarDecl;
import org.eclipse.etrice.core.room.util.RoomHelpers;
import org.eclipse.etrice.generator.fsm.base.FileSystemHelpers;
import org.eclipse.etrice.generator.fsm.generic.FSMExtensions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * collection of convenience functions for code generation
 */
@Singleton
@SuppressWarnings("all")
public class RoomExtensions extends FSMExtensions {
  public final String NEWLINE = System.getProperty("line.separator");
  
  private static String genDir = "/src-gen/";
  
  private static String genInfoDir = "/src-gen-info/";
  
  private static String genDocDir = "/doc-gen/";
  
  @Inject
  @Extension
  protected RoomHelpers _roomHelpers;
  
  public static String setDefaultGenDir() {
    return RoomExtensions.genDir = "/src-gen/";
  }
  
  public static String setDefaultGenInfoDir() {
    return RoomExtensions.genInfoDir = "/src-gen-info/";
  }
  
  public static String setDefaultGenDocDir() {
    return RoomExtensions.genDocDir = "/doc-gen/";
  }
  
  public static String setGenDir(final String dir) {
    return RoomExtensions.genDir = (("/" + dir) + "/");
  }
  
  public static String setGenInfoDir(final String dir) {
    return RoomExtensions.genInfoDir = (("/" + dir) + "/");
  }
  
  public static String setGenDocDir(final String dir) {
    return RoomExtensions.genDocDir = (("/" + dir) + "/");
  }
  
  /**
   * a specialized version of {@link #union(Iterable, Iterable)}
   * @param in1 an iterable of type T
   * @param in2 a second iterable of type T
   * @return the union of the two iterables as new list
   */
  public List<Port> punion(final Iterable<Port> in1, final Iterable<ExternalPort> in2) {
    final ArrayList<Port> ret = new ArrayList<Port>();
    final Consumer<ExternalPort> _function = new Consumer<ExternalPort>() {
      public void accept(final ExternalPort e) {
        Port _interfacePort = e.getInterfacePort();
        ret.add(_interfacePort);
      }
    };
    in2.forEach(_function);
    Iterables.<Port>addAll(ret, in1);
    return ret;
  }
  
  /**
   * @return the relative path to the destination folder for the generated code
   */
  public String getGenerationPathSegment() {
    return RoomExtensions.genDir;
  }
  
  /**
   * @return the relative path to the destination folder for the generated code
   */
  public String getGenerationInfoSegment() {
    return RoomExtensions.genInfoDir;
  }
  
  /**
   * @return the relative path to the destination folder for the generated documentation
   */
  public String getDocGenerationPathSegment() {
    return RoomExtensions.genDocDir;
  }
  
  /**
   * @param e an {@link EObject}
   * @return the URI of the EObject's resource as file string
   * 		(or an empty string if no such resource exists)
   */
  public String getModelPath(final EObject e) {
    Resource res = e.eResource();
    boolean _equals = Objects.equal(res, null);
    if (_equals) {
      return "";
    } else {
      URI _uRI = res.getURI();
      return _uRI.toFileString();
    }
  }
  
  /**
   * @param rc a {@link RoomClass}
   * @return the name of the room model which also serves as a package name
   */
  public String getPackage(final RoomClass rc) {
    EObject _eContainer = rc.eContainer();
    return ((RoomModel) _eContainer).getName();
  }
  
  /**
   * @param rc a {@link RoomClass}
   * @return the name of the room model followed by the class name and all . replaced with _
   */
  public String getFullyQualifiedName(final RoomClass rc) {
    String _package = this.getPackage(rc);
    String _replace = _package.replace(".", "_");
    String _plus = (_replace + "_");
    String _name = rc.getName();
    return (_plus + _name);
  }
  
  /**
   * @param packageName a dot (.) separated package anem
   * @return the input with dots replaced with slashes (/)
   */
  public String getPathFromPackage(final String packageName) {
    String _replaceAll = packageName.replaceAll("\\.", "/");
    return (_replaceAll + "/");
  }
  
  /**
   * @param rc a {@link RoomClass}
   * @return the relative folder path of the package
   * 		(as defined by the Java convention)
   */
  public String getPath(final RoomClass rc) {
    String _package = this.getPackage(rc);
    return this.getPathFromPackage(_package);
  }
  
  /**
   * @param e an {@link EObject}
   * @return the path of the Eclipse project containing the EObject's resource
   */
  public String getProjectPath(final EObject e) {
    final URI res = FileSystemHelpers.getProjectURI(e);
    boolean _equals = Objects.equal(res, null);
    if (_equals) {
      return "";
    }
    return res.toFileString();
  }
  
  /**
   * @param e an {@link EObject}
   * @return the concatenation of the object's project path
   * 		with the {@link #getGenerationPathSegment()}
   */
  public String getGenerationTargetPath(final EObject e) {
    String _projectPath = this.getProjectPath(e);
    String _generationPathSegment = this.getGenerationPathSegment();
    return (_projectPath + _generationPathSegment);
  }
  
  /**
   * @param e an {@link EObject}
   * @return the concatenation of the object's project path
   * 		with the {@link #getGenerationInfoSegment()}
   */
  public String getGenerationInfoPath(final EObject e) {
    String _projectPath = this.getProjectPath(e);
    String _generationInfoSegment = this.getGenerationInfoSegment();
    return (_projectPath + _generationInfoSegment);
  }
  
  /**
   * @param e an {@link EObject}
   * @return the concatenation of the objects project path
   * 		with the {@link #getDocGenerationPathSegment()}
   */
  public String getDocGenerationTargetPath(final EObject e) {
    String _projectPath = this.getProjectPath(e);
    String _docGenerationPathSegment = this.getDocGenerationPathSegment();
    return (_projectPath + _docGenerationPathSegment);
  }
  
  /**
   * makes a valid identifier from a path string
   * @param path a slash (/) separated path
   * @return the path with slashes (and colons as in replicated actors) replaced by underscores (_)
   */
  public String getPathName(final String path) {
    String _replaceAll = path.replaceAll("/", "_");
    return _replaceAll.replaceAll(":", "_");
  }
  
  /**
   * @param p a {@link Port}
   * @return a name for the associated port class
   */
  protected String _getPortClassName(final Port p) {
    String _xifexpression = null;
    GeneralProtocolClass _protocol = p.getProtocol();
    if ((_protocol instanceof ProtocolClass)) {
      GeneralProtocolClass _protocol_1 = p.getProtocol();
      boolean _isConjugated = p.isConjugated();
      boolean _isReplicated = p.isReplicated();
      _xifexpression = this.getPortClassName(((ProtocolClass) _protocol_1), _isConjugated, _isReplicated);
    } else {
      _xifexpression = "";
    }
    return _xifexpression;
  }
  
  /**
   * @param p a {@link ExternalPort}
   * @return a name for the associated port class
   */
  protected String _getPortClassName(final ExternalPort p) {
    Port _interfacePort = p.getInterfacePort();
    return this.getPortClassName(_interfacePort);
  }
  
  /**
   * @param sap a {@link SAP}
   * @return a name for the associated port class
   */
  protected String _getPortClassName(final SAP sap) {
    ProtocolClass _protocol = sap.getProtocol();
    return this.getPortClassName(_protocol, true);
  }
  
  /**
   * @param spp a {@link SPP}
   * @return a name for the associated port class
   */
  protected String _getPortClassName(final SPP spp) {
    ProtocolClass _protocol = spp.getProtocol();
    return this.getPortClassName(_protocol, false, true);
  }
  
  /**
   * @param svc a {@link ServiceImplementation}
   * @return a name for the associated port class
   */
  protected String _getPortClassName(final ServiceImplementation svc) {
    SPP _spp = svc.getSpp();
    ProtocolClass _protocol = _spp.getProtocol();
    return this.getPortClassName(_protocol, false, true);
  }
  
  /**
   * @param p a {@link ProtocolClass}
   * @param conj if <code>true</code> consider conjugate port, else regular
   * @return a name for the associated port class
   */
  public String getPortClassName(final ProtocolClass p, final boolean conj) {
    return this.getPortClassName(p, conj, false);
  }
  
  /**
   * @param p a {@link ProtocolClass}
   * @param conj if <code>true</code> consider conjugate port, else regular
   * @param repl if <code>true</code> class name for replicated port
   * 		else for plain port
   * @return a name for the associated port class
   */
  public String getPortClassName(final ProtocolClass p, final boolean conj, final boolean repl) {
    String _name = p.getName();
    String _xifexpression = null;
    if (conj) {
      _xifexpression = "Conj";
    } else {
      _xifexpression = "";
    }
    String _plus = (_name + _xifexpression);
    String _xifexpression_1 = null;
    if (repl) {
      _xifexpression_1 = "Repl";
    } else {
      _xifexpression_1 = "";
    }
    String _plus_1 = (_plus + _xifexpression_1);
    return (_plus_1 + "Port");
  }
  
  /**
   * @param pc a {@link ProtocolClass}
   * @param conj flag indicating the desired {@link PortClass}
   * @return the port class
   */
  public PortClass getPortClass(final ProtocolClass pc, final boolean conj) {
    if (conj) {
      return pc.getConjugated();
    } else {
      return pc.getRegular();
    }
  }
  
  /**
   * @param pc a {@link ProtocolClass}
   * @param conj flag indicating the desired communication direction
   * @return <code>true</code> if a send handler is specified for this direction
   */
  public boolean handlesSend(final ProtocolClass pc, final boolean conj) {
    PortClass _portClass = this.getPortClass(pc, conj);
    boolean _equals = Objects.equal(_portClass, null);
    if (_equals) {
      return false;
    } else {
      PortClass _portClass_1 = this.getPortClass(pc, conj);
      EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
      for (final MessageHandler hdlr : _msgHandlers) {
        List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, conj);
        Message _msg = hdlr.getMsg();
        boolean _contains = _allMessages.contains(_msg);
        if (_contains) {
          return true;
        }
      }
    }
    return false;
  }
  
  /**
   * @param pc a {@link ProtocolClass}
   * @param conj flag indicating the desired communication direction
   * @return <code>true</code> if a receive handler is specified for this direction
   */
  public boolean handlesReceive(final ProtocolClass pc, final boolean conj) {
    PortClass _portClass = this.getPortClass(pc, conj);
    boolean _equals = Objects.equal(_portClass, null);
    if (_equals) {
      return false;
    } else {
      PortClass _portClass_1 = this.getPortClass(pc, conj);
      EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
      for (final MessageHandler hdlr : _msgHandlers) {
        List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, (!conj));
        Message _msg = hdlr.getMsg();
        boolean _contains = _allMessages.contains(_msg);
        if (_contains) {
          return true;
        }
      }
    }
    return false;
  }
  
  /**
   * @param iii an {@link InterfaceItemInstance}
   * @return <code>true</code> if the interface item instance is logically conjugate
   */
  public boolean isConjugated(final InterfaceItemInstance iii) {
    if ((iii instanceof PortInstance)) {
      Port _port = ((PortInstance) iii).getPort();
      return _port.isConjugated();
    } else {
      if ((iii instanceof SAPInstance)) {
        return true;
      } else {
        if ((iii instanceof ServiceImplInstance)) {
          return false;
        } else {
          return false;
        }
      }
    }
  }
  
  /**
   * @param pc a {@link ProtocolClass}
   * @param conj flag indicating the desired communication direction
   * @return a list of defined receive {@link MessageHandler} for this direction
   */
  public List<MessageHandler> getReceiveHandlers(final ProtocolClass pc, final boolean conj) {
    PortClass _portClass = this.getPortClass(pc, conj);
    boolean _equals = Objects.equal(_portClass, null);
    if (_equals) {
      return new ArrayList<MessageHandler>();
    } else {
      ArrayList<MessageHandler> res = new ArrayList<MessageHandler>();
      PortClass _portClass_1 = this.getPortClass(pc, conj);
      EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
      for (final MessageHandler hdlr : _msgHandlers) {
        List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, (!conj));
        Message _msg = hdlr.getMsg();
        boolean _contains = _allMessages.contains(_msg);
        if (_contains) {
          res.add(hdlr);
        }
      }
      return res;
    }
  }
  
  /**
   * @param pc a {@link ProtocolClass}
   * @param conj flag indicating the desired communication direction
   * @return a list of defined send {@link MessageHandler} for this direction
   */
  public List<MessageHandler> getSendHandlers(final ProtocolClass pc, final boolean conj) {
    PortClass _portClass = this.getPortClass(pc, conj);
    boolean _equals = Objects.equal(_portClass, null);
    if (_equals) {
      return new ArrayList<MessageHandler>();
    } else {
      ArrayList<MessageHandler> res = new ArrayList<MessageHandler>();
      PortClass _portClass_1 = this.getPortClass(pc, conj);
      EList<MessageHandler> _msgHandlers = _portClass_1.getMsgHandlers();
      for (final MessageHandler hdlr : _msgHandlers) {
        List<Message> _allMessages = this._roomHelpers.getAllMessages(pc, conj);
        Message _msg = hdlr.getMsg();
        boolean _contains = _allMessages.contains(_msg);
        if (_contains) {
          res.add(hdlr);
        }
      }
      return res;
    }
  }
  
  /**
   * @param m a {@link Message}
   * @param conj flag indicating the desired communication direction
   * @return a send {@link MessageHandler} for this direction if it is defined, <code>null</code> else
   */
  public MessageHandler getSendHandler(final Message m, final boolean conj) {
    EObject _eContainer = m.eContainer();
    List<MessageHandler> _sendHandlers = this.getSendHandlers(((ProtocolClass) _eContainer), conj);
    final Function1<MessageHandler, Boolean> _function = new Function1<MessageHandler, Boolean>() {
      public Boolean apply(final MessageHandler e) {
        Message _msg = e.getMsg();
        return Boolean.valueOf(Objects.equal(_msg, m));
      }
    };
    return IterableExtensions.<MessageHandler>findFirst(_sendHandlers, _function);
  }
  
  /**
   * @param m a {@link Message}
   * @return <code>true</code> if this message is an incoming message
   */
  public boolean isIncoming(final Message m) {
    EObject _eContainer = m.eContainer();
    List<Message> _allIncomingMessages = this._roomHelpers.getAllIncomingMessages(((ProtocolClass) _eContainer));
    return _allIncomingMessages.contains(m);
  }
  
  /**
   * @param m a {@link Message}
   * @return a string that can be used as identifier for the message. It is prefixed with IN_ or OUT_
   * 		to avoid ambiguities
   */
  public String getCodeName(final Message m) {
    boolean _isIncoming = this.isIncoming(m);
    if (_isIncoming) {
      String _name = m.getName();
      return ("IN_" + _name);
    } else {
      String _name_1 = m.getName();
      return ("OUT_" + _name_1);
    }
  }
  
  /**
   * @param ac an {@link ActorClass}
   * @return <code>true</code> if an operation named 'stop' is defined with a void argument list and
   * 		void return type
   */
  public boolean overridesStop(final ActorClass ac) {
    boolean _or = false;
    EList<StandardOperation> _operations = ac.getOperations();
    final Function1<StandardOperation, Boolean> _function = new Function1<StandardOperation, Boolean>() {
      public Boolean apply(final StandardOperation e) {
        boolean _and = false;
        boolean _and_1 = false;
        String _name = e.getName();
        boolean _equals = Objects.equal(_name, "stop");
        if (!_equals) {
          _and_1 = false;
        } else {
          EList<VarDecl> _arguments = e.getArguments();
          boolean _isEmpty = _arguments.isEmpty();
          _and_1 = _isEmpty;
        }
        if (!_and_1) {
          _and = false;
        } else {
          RefableType _returnType = e.getReturnType();
          boolean _equals_1 = Objects.equal(_returnType, null);
          _and = _equals_1;
        }
        return Boolean.valueOf(_and);
      }
    };
    boolean _exists = IterableExtensions.<StandardOperation>exists(_operations, _function);
    if (_exists) {
      _or = true;
    } else {
      boolean _and = false;
      ActorClass _actorBase = ac.getActorBase();
      boolean _notEquals = (!Objects.equal(_actorBase, null));
      if (!_notEquals) {
        _and = false;
      } else {
        ActorClass _actorBase_1 = ac.getActorBase();
        boolean _overridesStop = this.overridesStop(_actorBase_1);
        _and = _overridesStop;
      }
      _or = _and;
    }
    return _or;
  }
  
  public BasicEList<AbstractInstance> getAllSubInstances(final StructureInstance ssi) {
    final BasicEList<AbstractInstance> result = new BasicEList<AbstractInstance>();
    final TreeIterator<EObject> it = ssi.eAllContents();
    while (it.hasNext()) {
      {
        final EObject obj = it.next();
        if ((obj instanceof AbstractInstance)) {
          result.add(((AbstractInstance) obj));
        }
      }
    }
    return result;
  }
  
  public String getPortClassName(final EObject p) {
    if (p instanceof Port) {
      return _getPortClassName((Port)p);
    } else if (p instanceof SAP) {
      return _getPortClassName((SAP)p);
    } else if (p instanceof SPP) {
      return _getPortClassName((SPP)p);
    } else if (p instanceof ExternalPort) {
      return _getPortClassName((ExternalPort)p);
    } else if (p instanceof ServiceImplementation) {
      return _getPortClassName((ServiceImplementation)p);
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(p).toString());
    }
  }
}
