/*
 * This file has been developed at the University of Munich, Chair for Programming & Software Engineering.
 * 
 * This file is licensed under the Eclipse Public License (EPL) 1.0
 * 
 */
package eu.mdd4soa.trans.smm2bpel.impl;

import javax.xml.namespace.QName;

import org.eclipse.bpel.apache.ode.deploy.model.dd.ProcessType;
import org.eclipse.bpel.apache.ode.deploy.model.dd.TDeployment;
import org.eclipse.bpel.apache.ode.deploy.model.dd.TInvoke;
import org.eclipse.bpel.apache.ode.deploy.model.dd.TProvide;
import org.eclipse.bpel.apache.ode.deploy.model.dd.TService;
import org.eclipse.bpel.apache.ode.deploy.model.dd.ddFactory;
import org.eclipse.emf.common.util.EList;

import eu.mdd4soa.smm.behaviour.ServiceActivity;
import eu.mdd4soa.smm.statik.Participant;
import eu.mdd4soa.smm.statik.ProvidedService;
import eu.mdd4soa.smm.statik.RequiredService;
import eu.mdd4soa.smm.statik.Service;
import eu.mdd4soa.trans.smm2bpel.impl.util.GPTracker;

public class DeploymentCreator {

	public static TDeployment create(GPTracker tracker, Participant participant, ServiceActivity behaviour) {

		DeploymentCreator deplc= new DeploymentCreator(tracker, participant, behaviour);
		deplc.execute();
		return deplc.getResult();
	}

	private static final ddFactory df= ddFactory.eINSTANCE;

	private GPTracker fTracker;

	private Participant fParticipant;

	private TDeployment fDeployment;

	private ServiceActivity fBehaviour;

	public DeploymentCreator(GPTracker tracker, Participant participant, ServiceActivity behaviour) {
		fTracker= tracker;
		fParticipant= participant;
		fBehaviour= behaviour;
	}

	private void execute() {
		fDeployment= df.createTDeployment();

		ProcessType pt= ddFactory.eINSTANCE.createProcessType();
		QName processQName= new QName(fTracker.getProcessNamespace(fBehaviour), fBehaviour.getName());
		pt.setName(processQName);

		fDeployment.getProcess().add(pt);

		EList<Service> partners= fParticipant.getPartners();
		for (Service partnerPoint : partners) {

			if (partnerPoint instanceof ProvidedService) {

				TProvide prov= df.createTProvide();
				prov.setPartnerLink(partnerPoint.getName());
				prov.setService(createServiceFor(partnerPoint));

				pt.getProvide().add(prov);

				if (!partnerPoint.getInterface().getUsed().isEmpty()) {

					// Callback
					TInvoke inv= df.createTInvoke();
					inv.setPartnerLink(partnerPoint.getName());

					TService service= df.createTService();
					service.setName(new QName(fTracker.getPartnerNamespace(partnerPoint.getName()), partnerPoint.getName() + "_callback"));
					service.setPort(partnerPoint.getName() + "_callback");
					inv.setService(service);

					pt.getInvoke().add(inv);
				}

			}

			if (partnerPoint instanceof RequiredService) {

				TInvoke inv= df.createTInvoke();
				inv.setPartnerLink(partnerPoint.getName());
				inv.setService(createServiceFor(partnerPoint));

				pt.getInvoke().add(inv);

				// TODO callback here too for the service itself...

			}

		}


	}

	private TService createServiceFor(Service partnerPoint) {
		TService service= df.createTService();
		service.setName(new QName(fTracker.getPartnerNamespace(partnerPoint.getName()), partnerPoint.getName()));
		service.setPort(partnerPoint.getName());
		return service;
	}

	private TDeployment getResult() {
		return fDeployment;
	}

}
