/*******************************************************************************
 * Copyright (c) 2016 ALL4TEC & 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:
 *     ALL4TEC & CEA LIST - initial API and implementation
 ******************************************************************************/
package org.polarsys.esf.esfarchitectureconcepts.impl;

import java.util.Collection;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.util.EcoreEList.UnmodifiableEList;
import org.eclipse.uml2.uml.Connector;
import org.eclipse.uml2.uml.ConnectorEnd;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.util.UMLUtil;
import org.polarsys.esf.esfarchitectureconcepts.IAbstractSConnectableElement;
import org.polarsys.esf.esfarchitectureconcepts.IESFArchitectureConceptsFactory;
import org.polarsys.esf.esfarchitectureconcepts.IMSConnector;
import org.polarsys.esf.esfarchitectureconcepts.ISBlock;
import org.polarsys.esf.esfarchitectureconcepts.ISPort;
import org.polarsys.esf.esfarchitectureconcepts.SDirection;
import org.polarsys.esf.esfcore.impl.GenericAbstractSElement;

/**
 * This class can override the generated class {@link SConnector} and will be
 * used by the custom factory.
 *
 * @author $Author: ymunoz $
 * @version $Revision: 168 $
 */
public class MSConnector extends SConnector implements IMSConnector {

	/**
	 * Default constructor.
	 */
	public MSConnector() {
		super();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getName() {
		return GenericAbstractSElement.getName(getBase_Connector());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getUUID() {
		return GenericAbstractSElement.getUUID(getBase_Connector());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EList<IAbstractSConnectableElement> getEndsList() {
		EList<IAbstractSConnectableElement> vSConnectableElementsList = new BasicEList<IAbstractSConnectableElement>();
		Connector vBase = getBase_Connector();

		if (vBase != null) {
			if (vBase.getEnds().size() >= 2) {
				ConnectorEnd vEnd1 = vBase.getEnds().get(0);
				ConnectorEnd vEnd2 = vBase.getEnds().get(1);
				if ((vEnd1.getRole() != null) && (vEnd2.getRole() != null)) {
					if ((UMLUtil.getStereotypeApplication(vEnd1.getRole(), SPort.class) != null)
							&& (UMLUtil.getStereotypeApplication(vEnd2.getRole(), SPort.class) != null)) {
						// Get the two Ports
						ISPort vSPort1 = (ISPort) UMLUtil.getStereotypeApplication(vEnd1.getRole(), SPort.class);
						ISPort vSPort2 = (ISPort) UMLUtil.getStereotypeApplication(vEnd2.getRole(), SPort.class);
						vSConnectableElementsList.add(vSPort1);
						vSConnectableElementsList.add(vSPort2);
					}
				}
			}
		}

		UnmodifiableEList<IAbstractSConnectableElement> vUSConnectableElementsList = new UnmodifiableEList<IAbstractSConnectableElement>(
				this, ESFArchitectureConceptsPackage.eINSTANCE.getSConnector_EndsList(),
				vSConnectableElementsList.size(), vSConnectableElementsList.toArray());
		return vUSConnectableElementsList;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ISBlock basicGetOwner() {
		Connector vBase = getBase_Connector();
		ISBlock vSBlock = IESFArchitectureConceptsFactory.eINSTANCE.createSBlock();

		if (vBase != null) {
			Element vOwner = vBase.getOwner();
			if ((vOwner != null) && (UMLUtil.getStereotypeApplication(vOwner, SBlock.class) != null)) {
				vSBlock = (SBlock) UMLUtil.getStereotypeApplication(vOwner, SBlock.class);
			}
		}
		return vSBlock;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EList<IAbstractSConnectableElement> getSourcesList() {
		EList<IAbstractSConnectableElement> vSourcesList = new BasicEList<IAbstractSConnectableElement>();
		Connector vBase = getBase_Connector();

		if (vBase != null) {
			EList<IAbstractSConnectableElement> vEnds = getEndsList();
			if (vEnds.size() >= 2) {
				vSourcesList.addAll(getSourcePorts(vEnds));
			}
		}

		UnmodifiableEList<IAbstractSConnectableElement> vUSourcesList = new UnmodifiableEList<IAbstractSConnectableElement>(
				this, ESFArchitectureConceptsPackage.eINSTANCE.getSConnector_EndsList(), vSourcesList.size(),
				vSourcesList.toArray());
		return vUSourcesList;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public EList<IAbstractSConnectableElement> getTargetsList() {
		EList<IAbstractSConnectableElement> vTargetsList = new BasicEList<IAbstractSConnectableElement>();
		Connector vBase = getBase_Connector();

		if (vBase != null) {
			EList<IAbstractSConnectableElement> vEnds = getEndsList();
			if (vEnds.size() >= 2) {
				vTargetsList.addAll(getTargetPorts(vEnds));
			}
		}

		UnmodifiableEList<IAbstractSConnectableElement> vUSTargetsList = new UnmodifiableEList<IAbstractSConnectableElement>(
				this, ESFArchitectureConceptsPackage.eINSTANCE.getSConnector_EndsList(), vTargetsList.size(),
				vTargetsList.toArray());
		return vUSTargetsList;
	}

	/**
	 * Verify what are the SPorts who play the source's role and get them.
	 *
	 * @param pSPorts
	 *            The SPorts from the SConnector
	 * @return The source SPorts
	 */
	private Collection<? extends IAbstractSConnectableElement> getSourcePorts(
			final EList<IAbstractSConnectableElement> pSPorts) {

		if (pSPorts.size() < 2) {
			throw new IllegalArgumentException(Integer.toString(pSPorts.size()));
		}

		EList<IAbstractSConnectableElement> vSourcePortsList = new BasicEList<IAbstractSConnectableElement>();

		// Get the two SPorts
		ISPort vSPort1 = (ISPort) pSPorts.get(0);
		ISPort vSPort2 = (ISPort) pSPorts.get(1);

		// Get the direction for each SPort
		SDirection vDirectionOfPort1 = vSPort1.getSDirection();
		SDirection vDirectionOfPort2 = vSPort2.getSDirection();

		// Get the owner for each Port
		Element vOwnerOfPort1 = vSPort1.getBase_Port().getOwner();
		Element vOwnerOfPort2 = vSPort2.getBase_Port().getOwner();

		// Get the part with port for each ConnectorEnd
		Element vPartWithPort1 = getBase_Connector().getEnds().get(0).getPartWithPort();
		Element vPartWithPort2 = getBase_Connector().getEnds().get(1).getPartWithPort();

		// 1. Verify if the connection is between SBlock and SPart
		if (((vPartWithPort1 != null) && (vPartWithPort2 == null))
				|| ((vPartWithPort1 == null) && (vPartWithPort2 != null))) {

			// 1.1 Verify if the connection is between : [SBlock::SPort_IN] ->
			// [SPart::SPort_IN]
			if (SDirection.IN.equals(vDirectionOfPort1) && SDirection.IN.equals(vDirectionOfPort2)) {

				// If "ownerOfPort1" contains "partWithPort2" than "SPort1" is
				// the source
				if ((vPartWithPort2 != null) && (vOwnerOfPort1.getOwnedElements().contains(vPartWithPort2))) {
					vSourcePortsList.add(vSPort1);

					// If "ownerOfPort2" contains "partWithPort1" than "SPort2"
					// is the source
				} else if ((vPartWithPort1 != null) && (vOwnerOfPort2.getOwnedElements().contains(vPartWithPort1))) {
					vSourcePortsList.add(vSPort2);
				}

				// 1.2 If the connection is between : [SPart::SPort_OUT] ->
				// [SBlock::SPort_OUT]
			} else if (SDirection.OUT.equals(vDirectionOfPort1) && SDirection.OUT.equals(vDirectionOfPort2)) {

				// If "partWithPort2" is child of "ownerOfPort1" than "SPort2"
				// is the source
				if ((vPartWithPort2 != null) && (vPartWithPort2.getOwner().equals(vOwnerOfPort1))) {
					vSourcePortsList.add(vSPort2);

					// If "partWithPort1" is child of "ownerOfPort2" than return
					// "SPort1" is the source
				} else if ((vPartWithPort1 != null) && (vPartWithPort1.getOwner().equals(vOwnerOfPort2))) {
					vSourcePortsList.add(vSPort1);
				}
			}

			// 2. If the connection is between : [SPart::SPort_OUT] ->
			// [SPart::SPort_IN]
		} else if ((vPartWithPort1 != null) && (vPartWithPort2 != null)) {

			// If the direction of "SPort1" is OUT and the direction of "SPort2"
			// is IN than "SPort1" is the source
			if (SDirection.OUT.equals(vDirectionOfPort1) && SDirection.IN.equals(vDirectionOfPort2)) {
				vSourcePortsList.add(vSPort1);

				// If the direction of "SPort2" is OUT and the direction of
				// "SPort1" is IN than "SPort2" is the source
			} else if (SDirection.OUT.equals(vDirectionOfPort2) && SDirection.IN.equals(vDirectionOfPort1)) {
				vSourcePortsList.add(vSPort2);
			}
		}
		return vSourcePortsList;
	}

	/**
	 * Verify what are the SPorts who play the target's role and get them.
	 *
	 * @param pSPorts
	 *            The SPorts from the SConnector
	 * @return The target SPorts
	 */
	private Collection<? extends IAbstractSConnectableElement> getTargetPorts(
			final EList<IAbstractSConnectableElement> pSPorts) {

		if (pSPorts.size() != 2) {
			throw new IllegalArgumentException(Integer.toString(pSPorts.size()));
		}

		EList<IAbstractSConnectableElement> vTargetPortsList = new BasicEList<IAbstractSConnectableElement>();

		// Get the two SPorts
		ISPort vSPort1 = (ISPort) pSPorts.get(0);
		ISPort vSPort2 = (ISPort) pSPorts.get(1);

		// Get the type for each SPort
		SDirection vDirectionOfPort1 = vSPort1.getSDirection();
		SDirection vDirectionOfPort2 = vSPort2.getSDirection();

		// Get the owner for each Port
		Element vOwnerOfPort1 = vSPort1.getBase_Port().getOwner();
		Element vOnerOfPort2 = vSPort2.getBase_Port().getOwner();

		// Get the part with port for each ConnectorEnd
		Element vParttWithPort1 = getBase_Connector().getEnds().get(0).getPartWithPort();
		Element vPartWithPort2 = getBase_Connector().getEnds().get(1).getPartWithPort();

		// 1. Verify if the connection is between Block and Part
		if (((vParttWithPort1 != null) && (vPartWithPort2 == null))
				|| ((vParttWithPort1 == null) && (vPartWithPort2 != null))) {
			// 1.1 Verify if the connection is between : [SBlock::SPort_IN] ->
			// [SPart::SPort_IN]
			if (SDirection.IN.equals(vDirectionOfPort1) && SDirection.IN.equals(vDirectionOfPort2)) {

				// If "ownerOfPort1" contains "partWithPort2" than return
				// "SPort2" is the target
				if ((vPartWithPort2 != null) && (vOwnerOfPort1.getOwnedElements().contains(vPartWithPort2))) {
					vTargetPortsList.add(vSPort2);

					// If "ownerOfPort2" contains "partWithPort1" than "SPort1"
					// is the target
				} else if ((vParttWithPort1 != null) && (vOnerOfPort2.getOwnedElements().contains(vParttWithPort1))) {
					vTargetPortsList.add(vSPort1);
				}

				// 1.2 If the connection is between : [SPart::SPort_OUT] ->
				// [SBlock::SPort_OUT]
			} else if (SDirection.OUT.equals(vDirectionOfPort1) && SDirection.OUT.equals(vDirectionOfPort2)) {
				// If "partWithPort2" is child of "ownerOfPort1" than "SPort1"
				// is the target
				if ((vPartWithPort2 != null) && (vPartWithPort2.getOwner().equals(vOwnerOfPort1))) {
					vTargetPortsList.add(vSPort1);

					// If "partWithPort1" is child of "ownerOfPort2" than
					// "SPort2" is the target
				} else if ((vParttWithPort1 != null) && (vParttWithPort1.getOwner().equals(vOnerOfPort2))) {
					vTargetPortsList.add(vSPort2);
				}
			}

			// 2. If the connection is between : [SPart::SPort_OUT] ->
			// [SPart::SPort_IN]
		} else if ((vParttWithPort1 != null) && (vPartWithPort2 != null)) {
			// If the direction of "SPort1" is OUT and the direction of "SPort2"
			// is IN than "SPort2" is the target
			if (SDirection.OUT.equals(vDirectionOfPort1) && SDirection.IN.equals(vDirectionOfPort2)) {
				vTargetPortsList.add(vSPort2);

				// If the direction of "SPort2" is OUT and the direction of
				// "SPort1" is IN than "SPort1" is the target
			} else if (SDirection.OUT.equals(vDirectionOfPort2) && SDirection.IN.equals(vDirectionOfPort1)) {
				vTargetPortsList.add(vSPort1);
			}
		}
		return vTargetPortsList;
	}
}
