/*****************************************************************************
 * Copyright (c) 2013 CEA LIST.
 *
 *
 * 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:
 *  Ansgar Radermacher  ansgar.radermacher@cea.fr
 *  Shuai Li (CEA LIST) <shuai.li@cea.fr> - Bug 530651
 *
 *****************************************************************************/

package org.eclipse.papyrus.designer.components.transformation;

import java.util.List;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.papyrus.designer.components.FCM.PortKind;
import org.eclipse.papyrus.designer.components.FCM.TemplatePort;
import org.eclipse.papyrus.designer.languages.common.base.ElementUtils;
import org.eclipse.papyrus.designer.transformation.core.utils.ComparisonUtils;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.EncapsulatedClassifier;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Port;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Type;
import org.eclipse.uml2.uml.util.UMLUtil;

public class PortUtils {

	/**
	 * Return the provided interface associated with the UML port, i.e.
	 * the derived attribute of the FCM profile
	 *
	 * @param port
	 *            the UML port
	 * @return the provided interface
	 */
	public static Interface getProvided(Port port) {
		if (port.getProvideds().size() > 0) {
			// return first standard UML provided port
			return port.getProvideds().get(0);
		}
		return null;
	}

	/**
	 * Return all provided interfaces associated with the UML port, i.e.
	 * the derived attribute of the FCM profile
	 *
	 * @param port
	 *            the UML port
	 * @return the provided interface
	 */
	public static List<Interface> getProvideds(Port port) {
		if (port.getProvideds().size() > 0) {
			// return all provided interfaces
			return port.getProvideds();
		}
		return null;
	}

	/**
	 * Return the required interface associated with the UML port, i.e.
	 * the derived attribute of the FCM profile
	 *
	 * @param port
	 *            the UML port
	 * @return the required interface
	 */
	public static Interface getRequired(Port port) {
		if (port.getRequireds().size() > 0) {
			// return first standard UML required port
			return port.getRequireds().get(0);
		}
		return null;
	}

	/**
	 * Return all required interfaces associated with the UML port, i.e.
	 * the derived attribute of the FCM profile
	 *
	 * @param port
	 *            the UML port
	 * @return the required interface
	 */
	public static List<Interface> getRequireds(Port port) {
		if (port.getRequireds().size() > 0) {
			// return all required interfaces
			return port.getRequireds();
		}
		return null;
	}

	/**
	 * Return the FCM port (static profile) from a given UML port
	 *
	 * @param port
	 *            a port
	 * @return the associated FCM port
	 */
	public static org.eclipse.papyrus.designer.components.FCM.Port getFCMport(Port port) {
		return UMLUtil.getStereotypeApplication(port, org.eclipse.papyrus.designer.components.FCM.Port.class);
	}

	/**
	 * Return the value of the FCM stereotype attribute "type"
	 * 
	 * @param port
	 *            a UML port
	 * @return the value of the type attribute
	 */
	public static Type getFCMType(Port port) {
		org.eclipse.papyrus.designer.components.FCM.Port fcmPort = getFCMport(port);
		if (fcmPort != null) {
			return fcmPort.getType();
		}
		return null;
	}

	/**
	 * Returns all ports (including inherited ones) for an encapsulated classifier
	 * It will also flatten extended ports
	 *
	 * @param ec
	 *            an encapsulated classifier
	 * @return the list of ports, including inherited ones
	 */
	public static EList<Port> getAllPorts(EncapsulatedClassifier ec) {
		EList<Port> ports = new BasicEList<Port>();
		for (Property attribute : ec.getAllAttributes()) {
			if (attribute instanceof Port) {
				ports.add((Port) attribute);
			}
		}

		return ports;
	}

	/**
	 * Returns all ports for an encapsulated classifier. Inherited ports are
	 * included, except if the superclass is already a component implementation.
	 * The motivation for this function is that ports inherited by a
	 * component implementation have already corresponding operations/attributes,
	 * only ports inherited by types need these definitions in subclasses.
	 * TODO: support for abstract implementations that partially implement ports
	 *
	 * @param ec
	 *            an encapsulated classifier
	 * @return the list of ports, (partly) including inherited ones
	 */
	public static EList<Port> getAllPorts2(EncapsulatedClassifier ec) {
		EList<Port> ports = new BasicEList<Port>();

		ports.addAll(ec.getOwnedPorts());

		for (Classifier general : ec.getGenerals()) {
			if ((general instanceof EncapsulatedClassifier) && (general.isAbstract())) {
				ports.addAll(getAllPorts2((EncapsulatedClassifier) general));
			}
		}
		return ports;
	}

	/**
	 * When given a list of ports, flatten the extended ports within this list
	 * and return a list of port-infos, i.e. information about ports.
	 *
	 * @param ports
	 *            A list of ports
	 * @return A list of port-infos
	 */
	public static EList<PortInfo> flattenExtendedPorts(EList<Port> ports) {
		EList<PortInfo> portInfos = new BasicEList<PortInfo>();
		for (Port port : ports) {
			portInfos.addAll(flattenExtendedPort(port));
		}
		return portInfos;
	}


	/**
	 * Flatten the given extended port and return a list of port-infos.
	 *
	 * @param port
	 * @return A list of port-infos
	 */
	public static EList<PortInfo> flattenExtendedPort(Port port) {
		EList<PortInfo> portInfos = new BasicEList<PortInfo>();
		if (isExtendedPort(port)) {
			org.eclipse.papyrus.designer.components.FCM.Port fcmPort = getFCMport(port);
			org.eclipse.uml2.uml.Class cl;
			if (isTemplatePort(port)) {
				TemplatePort tp = UMLUtil.getStereotypeApplication(port, TemplatePort.class);
				if (tp.getBoundType() == null) {
					Activator.log.debug("Bound type of template port is null, choosing base class of kind instead"); //$NON-NLS-1$
					cl = fcmPort.getKind().getBase_Class();
				} else {
					cl = tp.getBoundType().getBase_Class();
				}
			} else {
				cl = fcmPort.getKind().getBase_Class();
			}
			if ((cl != null) && (getAllPorts(cl).size() > 0)) {
				EList<Port> extendedPorts = getAllPorts(cl);
				for (Port extendedPort : extendedPorts) {
					portInfos.add(new PortInfo(extendedPort, port));
				}
			}
		} else {
			portInfos.add(new PortInfo(port, null));
		}
		return portInfos;
	}

	/**
	 * Return true, if the passed port is an extended port
	 *
	 * @param port
	 *            a UML port
	 * @return true, if port is an extended port
	 */
	public static boolean isExtendedPort(Port port) {
		org.eclipse.papyrus.designer.components.FCM.Port fcmPort = getFCMport(port);
		if ((fcmPort != null) && (fcmPort.getKind() != null)) {
			org.eclipse.uml2.uml.Class cl = fcmPort.getKind().getBase_Class();
			return ((cl != null) && (getAllPorts(cl).size() > 0));
		}
		return false;
	}

	/**
	 * Return true, if the passed port is a template port
	 *
	 * @param port
	 *            a UML port
	 * @return true, if port is a template port
	 */
	public static boolean isTemplatePort(Port port) {
		return StereotypeUtil.isApplied(port, TemplatePort.class);
	}

	/**
	 * Return the port kind, an element of the static profile
	 *
	 * @param port
	 *            a UML port
	 * @return the port kind
	 */
	public static PortKind getKind(Port port) {
		org.eclipse.papyrus.designer.components.FCM.Port fcmPort = getFCMport(port);
		if (fcmPort != null) {
			return fcmPort.getKind();
		}
		return null;
	}

	/**
	 * Check whether two ports have the same port kind. Since different models apparently
	 * use different Java instances for the same port kind, the check is therefore based
	 * on the equality of full qualified name.
	 *
	 * @param portA
	 * @param portB
	 * @return true, if port kinds are identical
	 */
	public static boolean sameKinds(Port portA, Port portB) {
		PortKind kindA = getKind(portA);
		PortKind kindB = getKind(portB);
		return ComparisonUtils.sameObject(kindA, kindB);
	}

	/**
	 * Check whether two ports match, i.e. have the same type & kind but different conjugation (assembly)
	 * or same type, kind and conjugation (delegation). The ports must have the FCM port stereotype.
	 *
	 * @param portA
	 *            first port
	 * @param portB
	 *            second port
	 * @param isAssembly
	 *            true, if the ports should be connected by an assembly connector (i.e. no delegation)
	 * @return true, if ports match
	 */
	public static boolean matches(Port portA, Port portB, boolean isAssembly) {
		org.eclipse.papyrus.designer.components.FCM.Port fcmPortA = UMLUtil.getStereotypeApplication(portA, org.eclipse.papyrus.designer.components.FCM.Port.class);
		org.eclipse.papyrus.designer.components.FCM.Port fcmPortB = UMLUtil.getStereotypeApplication(portB, org.eclipse.papyrus.designer.components.FCM.Port.class);
		if ((fcmPortA == null) || (fcmPortB == null)) {
			return false;
		}
		// require strict identity for type (unlike the kind, both must be in the same resource set)
		boolean sameTypeAndKind = (fcmPortA.getType() == fcmPortB.getType()) &&
				ComparisonUtils.sameObject(fcmPortA.getKind(), fcmPortB.getKind());
		if (isAssembly) {
			return (sameTypeAndKind && portA.isConjugated() != portB.isConjugated());
		} else {
			// delegation
			return (sameTypeAndKind && portA.isConjugated() == portB.isConjugated());
		}
	}

	/**
	 * Check whether two ports are compatible. i.e. either match or are compatible interface wise
	 *
	 * @param portA
	 * @param portB
	 * @param isAssembly
	 *            true, if the ports should be connected by an assembly connector (i.e. no delegation)
	 * @return true, if the two ports are compatible
	 */
	public static boolean isCompatible(Port portA, Port portB, boolean isAssembly) {
		if (matches(portA, portB, isAssembly)) {
			return true;
		}
		// no match found, try weaker condition: find 1st match for provided ...
		if (isAssembly) {
			Interface reqA = PortUtils.getRequired(portA);
			Interface reqB = PortUtils.getRequired(portB);
			Interface prodA = PortUtils.getProvided(portA);
			Interface prodB = PortUtils.getProvided(portB);
			return (((reqA == null) && isSubInterface(prodA, reqB))
					|| ((reqB == null) && isSubInterface(prodB, reqA))
					|| (isSubInterface(prodA, reqB) && isSubInterface(prodB, reqA)));
		} else {
			return (PortUtils.getProvided(portA) == PortUtils.getProvided(portB)) &&
					(PortUtils.getRequired(portB) == PortUtils.getRequired(portA));
		}
	}

	/**
	 * return true, if intfA is a sub-interface of intfB, i.e. either both interfaces are identical or one of the
	 * super-classes (generalizations of intfA) is identical to B.
	 * more general than interfaceB.
	 *
	 * @param intfA
	 * @param intfB
	 * @return true, if intfA is a sub-interface of intfB
	 */
	public static boolean isSubInterface(Interface intfA, Interface intfB) {
		return (intfA == intfB) || (intfA != null && intfA.getGenerals().contains(intfB));
	}

	/**
	 * Return a port with a given name and type
	 * TODO: Currently unused. Would be useful for bootloader generation, but
	 * bootloader generation is not specific for component based approach, i.e.
	 * cannot access PortUtils
	 *
	 * @param component
	 *            the name of a component
	 * @param portName
	 *            the name of a potential port
	 * @param qTypeName
	 *            the required type of that port
	 * @return a port of the component with the given name and type combination or null
	 */
	public static Port getPortWithType(Class component, String portName, String qTypeName) {
		if (component != null) {
			Element portElem = ElementUtils.getNamedElementFromList(component.getAllAttributes(), portName);
			if (portElem instanceof Port) {
				Port port = (Port) portElem;
				// check, if port has expected type
				if (qTypeName.equals(port.getType().getQualifiedName())) {
					return port;
				}
			}
		}
		return null;
	}
}
