package org.eclipse.papyrus.designer.components.modellibs.zmq.iconfigurators;

import java.util.ArrayList;

import org.eclipse.emf.common.util.EList;
import org.eclipse.papyrus.designer.deployment.tools.AllocUtils;
import org.eclipse.papyrus.designer.deployment.tools.DepPlanUtils;
import org.eclipse.papyrus.designer.deployment.tools.DepUtils;
import org.eclipse.papyrus.designer.transformation.base.utils.ElementUtils;
import org.eclipse.papyrus.designer.transformation.base.utils.TransformationRTException;
import org.eclipse.papyrus.designer.transformation.extensions.IInstanceConfigurator;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Slot;
import org.eclipse.uml2.uml.UMLPackage;

public class ZMQSocketRuntimeLBConfigurator implements IInstanceConfigurator {

	private static final String PORT_NUMBER = "portNumber"; //$NON-NLS-1$
	private static final String IP_ADDRESS = "ipAddress"; //$NON-NLS-1$

	public static final String tcpConfigName = "tcpipConfig"; //$NON-NLS-1$
	public static final String ROLE = "role";

	public void configureInstance(InstanceSpecification instance,
			Property componentPart, InstanceSpecification parentInstance) {
		Classifier socketRuntime = DepUtils.getClassifier(instance);
		if (socketRuntime != null) {
			Package cdp = instance.getNearestPackage();
			EList<InstanceSpecification> allAllocs = AllocUtils.getAllNodes(DepUtils.getInstances(cdp));
			//InstanceSpecification node = AllocUtils.getNode(instance.eContainer().eContainer());

			Property tcpConfig = socketRuntime.getAttribute(tcpConfigName, null);
			if (tcpConfig == null) {
				throw new TransformationRTException(
					String.format("Cannot find property %s in class SocketRuntime", tcpConfigName));
			}
			Property propRole = socketRuntime.getAttribute(ROLE, null);
			if (propRole == null) {
				throw new TransformationRTException(
					String.format("Cannot find property %s in class SocketRuntime", ROLE));
			}
			// Property tcpConfigCopy = containerContext.copy.getCopy(tcpConfig);
			// tcpConfigCopy.setUpper(allAllocs.size());
			
			Classifier tcpConfigCl = (Classifier) tcpConfig.getType();
			Property propIPaddress = tcpConfigCl.getAttribute(IP_ADDRESS, null);
			Property propPortNumber = tcpConfigCl.getAttribute(PORT_NUMBER, null);
			
			ArrayList<Slot> addressSlots = new ArrayList<>();
			ArrayList<Slot> portSlots = new ArrayList<>();
			for (Slot slot : allAllocs.get(0).getSlots()) {
				if (slot.getDefiningFeature() == propIPaddress) {
					addressSlots.add(slot);
				}
				if (slot.getDefiningFeature() == propPortNumber) {
					portSlots.add(slot);
				}
			}
			
			String instName1 = instance.getName() + "." + tcpConfigName + //$NON-NLS-1$
					"[" + 0 + "]"; //$NON-NLS-1$ //$NON-NLS-2$
			
			String instName2 = instance.getName() + "." + tcpConfigName + //$NON-NLS-1$
					"[" + 1 + "]"; //$NON-NLS-1$ //$NON-NLS-2$
			
			if (addressSlots.size() != 2 || portSlots.size() != 2) {
				throw new TransformationRTException(
						String.format("Configuration is not correct", ROLE));
			}
			
			if (cdp.getPackagedElement(instName1) == null) {
				InstanceSpecification isConfig = (InstanceSpecification)
						cdp.createPackagedElement(instName1, UMLPackage.eINSTANCE.getInstanceSpecification());
				DepPlanUtils.configureProperty(isConfig, propIPaddress, ElementUtils.quoteString(
						DepUtils.firstValue(addressSlots.get(0)).stringValue()));
				DepPlanUtils.configureProperty(isConfig, propPortNumber,
						DepUtils.firstValue(portSlots.get(0)).integerValue());
			}
			
			if (cdp.getPackagedElement(instName2) == null) {
				InstanceSpecification isConfig = (InstanceSpecification)
						cdp.createPackagedElement(instName1, UMLPackage.eINSTANCE.getInstanceSpecification());
				DepPlanUtils.configureProperty(isConfig, propIPaddress, ElementUtils.quoteString(
						DepUtils.firstValue(addressSlots.get(1)).stringValue()));
				DepPlanUtils.configureProperty(isConfig, propPortNumber,
						DepUtils.firstValue(portSlots.get(1)).integerValue());
			}
			
			
			int i = 0;
			for (InstanceSpecification alloc : allAllocs) {
				// array configuration: create multiple slots for same defining feature
				// DepPlanUtils.createDepPlan(cdp, composite, name)
				
				// the configuration of arrays via slots is ambiguous. It is not clear which index of
				// a defining feature is pointed to by a slot. Pragmatically, we add the index to the instance
				// name.
				
				/* Get all slots that are associated with property */
				
//				Classifier tcpConfigCl = (Classifier) tcpConfig.getType();
//				Property propIPaddress = tcpConfigCl.getAttribute(IP_ADDRESS, null);
//				Property propPortNumber = tcpConfigCl.getAttribute(PORT_NUMBER, null);
//				
//				ArrayList<Slot> addressSlots = new ArrayList<>();
//				ArrayList<Slot> portSlots = new ArrayList<>();
//				for (Slot slot : alloc.getSlots()) {
//					if (slot.getDefiningFeature() == propIPaddress) {
//						addressSlots.add(slot);
//					}
//					if (slot.getDefiningFeature() == propPortNumber) {
//						portSlots.add(slot);
//					}
//				}
//				
//				String instName1 = instance.getName() + "." + tcpConfigName + //$NON-NLS-1$
//						"[" + 0 + "]"; //$NON-NLS-1$ //$NON-NLS-2$
//				
//				String instName2 = instance.getName() + "." + tcpConfigName + //$NON-NLS-1$
//						"[" + 1 + "]"; //$NON-NLS-1$ //$NON-NLS-2$
//				
//				if (addressSlots.size() != 2 || portSlots.size() != 2) {
//					
//				}
				
				
//				if (cdp.getPackagedElement(instName) != null) {
//					// element exists already. Has been added in context of other node
//					continue;
//				}
//				
//				InstanceSpecification isConfig = (InstanceSpecification)
//					cdp.createPackagedElement(instName, UMLPackage.eINSTANCE.getInstanceSpecification());
//				Classifier tcpConfigCl = (Classifier) tcpConfig.getType();
//				isConfig.getClassifiers().add(tcpConfigCl);
//				DepPlanUtils.createSlot(cdp, instance, isConfig, tcpConfig);
//				Property propIPaddress = tcpConfigCl.getAttribute(IP_ADDRESS, null);
//				Property propPortNumber = tcpConfigCl.getAttribute(PORT_NUMBER, null);
				Slot slotIPaddress = DepUtils.getSlot(alloc, propIPaddress);
				Slot slotPortNumber = DepUtils.getSlot(alloc, propPortNumber);
//				DepPlanUtils.configureProperty(isConfig, propIPaddress, Utils.quoteString(
//						DepUtils.firstValue(slotIPaddress).stringValue()));
//				DepPlanUtils.configureProperty(isConfig, propPortNumber,
						//DepUtils.firstValue(slotPortNumber).integerValue());
				i++;
			}
		}
	}

}
