/**
 * 
 */
package org.ellectra.jbigenerator;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.wsdl.*;
import javax.wsdl.factory.*;
import javax.wsdl.xml.*;
import org.oasisOpen.docs.wsbpel.x20.process.executable.impl.*;
import org.oasisOpen.docs.wsbpel.x20.process.executable.*;
/**
 * @author tdi
 *
 */
public class jbigenerator {
	
	
	
	
	////////////////////////////////////////////////////////////////////////////////////////////
	// The Following functions handle the parsing or WSDL
	
	public static String GetPortType(String Key)
	{
		String szPort;
		
		szPort=Key.substring(Key.indexOf("}")+1);
		
		return szPort;
	}
	
	public static String GetNamespaceForPortType(String Key)
	{
		String szPort;
		
		
		szPort=Key.substring(Key.indexOf("{")+1, Key.indexOf("}"));
		return szPort;
	}
	
		
	public static String WSDLGetPortNS(String szfilename)
	{
		try
		{
		WSDLFactory factory = WSDLFactory.newInstance();
		WSDLReader reader = factory.newWSDLReader();	
		reader.setFeature("javax.wsdl.verbose", true);
		reader.setFeature("javax.wsdl.importDocuments", true);
		Definition def = reader.readWSDL(null, szfilename);
		///get porttype
		Map PortType=def.getPortTypes();

		Set keys = PortType.keySet();         // The set of keys in the map.
     	Iterator keyIter = keys.iterator();
     	while (keyIter.hasNext()) {
     		Object key = keyIter.next();  // Get the next key.
     		Object value = PortType.get(key);  // Get the value for that key.
     		//System.out.println( "PortNS = "+GetNamespaceForPortType(key.toString()));
     		//System.out.println( "Port = "+ GetPortType(key.toString()));
     		return GetNamespaceForPortType(key.toString());
     	}
    	return "0";
     	//read namespace
     	//Map Namespace=def.getNamespaces();
		//System.out.println(Namespace);
		}
		catch (WSDLException e)
		{
			e.printStackTrace();
			return "-1";
		}
	}
	
	public static String WSDLGetPort(String szfilename)
	{
		try
		{
		WSDLFactory factory = WSDLFactory.newInstance();
		WSDLReader reader = factory.newWSDLReader();	
		reader.setFeature("javax.wsdl.verbose", true);
		reader.setFeature("javax.wsdl.importDocuments", true);
		Definition def = reader.readWSDL(null, szfilename);
		///get porttype
		Map PortType=def.getPortTypes();

		Set keys = PortType.keySet();         // The set of keys in the map.
     	Iterator keyIter = keys.iterator();
     	while (keyIter.hasNext()) {
     		Object key = keyIter.next();  // Get the next key.
     		Object value = PortType.get(key);  // Get the value for that key.
     		//System.out.println( "PortNS = "+GetNamespaceForPortType(key.toString()));
     		//System.out.println( "Port = "+ GetPortType(key.toString()));
     		return GetPortType(key.toString());
     	}
    	return "0";
     	//read namespace
     	//Map Namespace=def.getNamespaces();
		//System.out.println(Namespace);
		}
		catch (WSDLException e)
		{
			e.printStackTrace();
			return "-1";
		}
	}
	////////////////////////////////////////////////////////////////////////////////////////////
	
	////////////////////////////////////////////////////////////////////////////////////////////
	// The following functions handle the parsing of .bpel files (xml based on modified bpel.xsd)
	public static int GetBPELMaximumPartnersLinks(String filename)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
		//	String tname=pProcess.getTargetNamespace();
			
			TPartnerLinks pTL=pProcess.getPartnerLinks();
			TPartnerLink[] pArray=pTL.getPartnerLinkArray();
			return pArray.length;
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return -1;
		}
		
	}
	
	public static String GetBPELNameSpace(String filename)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
			String tname=pProcess.getTargetNamespace();
			return tname;
			
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return "-1";
		}
		
	}
	
	public static String GetBpelName(String filename,int pos)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
		
			
			TPartnerLinks pTL=pProcess.getPartnerLinks();
			TPartnerLink[] pArray=pTL.getPartnerLinkArray();
			
			return pArray[pos].getName();
			
			
			
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return "-1";
		}
		
	}
	
	public static String GetBpelMyRole(String filename,int pos)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
		
			
			TPartnerLinks pTL=pProcess.getPartnerLinks();
			TPartnerLink[] pArray=pTL.getPartnerLinkArray();
			
			return pArray[pos].getMyRole();
			
			
			
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return "-1";
		}
		
	}
	
	public static String GetBpelPartenerRole(String filename,int pos)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
		
			
			TPartnerLinks pTL=pProcess.getPartnerLinks();
			TPartnerLink[] pArray=pTL.getPartnerLinkArray();
			
			return pArray[pos].getPartnerRole();
			
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return "-1";
		}
		
	}
	////////////////////////////////////////////////////////////////////////////////////////////
	
	/////////////////////////////////////////////////////////////////////////////////////////
	// debug functions which print the parsing files
	// only to be called in developing phase
	public static String ReadBpelPrint(String filename)
	{
		File input = new File(filename);
		try{
			ProcessDocument pDoc=ProcessDocument.Factory.parse(input);
			TProcess pProcess=pDoc.getProcess();
			
			String tname=pProcess.getTargetNamespace();
			
			TPartnerLinks pTL=pProcess.getPartnerLinks();
			TPartnerLink[] pArray=pTL.getPartnerLinkArray();
			
			System.out.println( "namespace = "+ tname);
			System.out.println( "name = "+ pArray[0].getName());
			System.out.println( "role = "+ pArray[0].getMyRole());
			System.out.println( "prole = "+ pArray[0].getPartnerRole());
			
			System.out.println( "name = "+ pArray[1].getName());
			System.out.println( "role = "+ pArray[1].getMyRole());
			System.out.println( "prole = "+ pArray[1].getPartnerRole());
		}catch(Exception e)
		{
			e.printStackTrace();
			
			return "ERROR on Readbpel";
		}
		return "OK";
	}
	
	public static void WorkWSDLPrint(String szfilename)
	{
		try
		{
		WSDLFactory factory = WSDLFactory.newInstance();
		WSDLReader reader = factory.newWSDLReader();	
		reader.setFeature("javax.wsdl.verbose", true);
		reader.setFeature("javax.wsdl.importDocuments", true);
		Definition def = reader.readWSDL(null, szfilename);
		///get porttype
		Map PortType=def.getPortTypes();

		Set keys = PortType.keySet();         // The set of keys in the map.
     	Iterator keyIter = keys.iterator();
     	while (keyIter.hasNext()) {
     		Object key = keyIter.next();  // Get the next key.
     		Object value = PortType.get(key);  // Get the value for that key.
     		System.out.println( "PortNS = "+GetNamespaceForPortType(key.toString()));
     		System.out.println( "Port = "+ GetPortType(key.toString()));
     	}
     	//read namespace
     	//Map Namespace=def.getNamespaces();
		//System.out.println(Namespace);
		}
		catch (WSDLException e)
		{
		e.printStackTrace();
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////////////////////
	public static void main(String[] args) {

		/*Argument             Description
		 *  0                  type (0=bpel jbi.xml and 1=composition jbi.xml 2= both)
		 *  1                  Bpel file (.bpel or .xml)
		 *  2                  Bpel wsdl file (.wsdl)
		 *  3                  targetname space for bpel process
		 *  4                  Main jar filename
		 *  5                  Composition name
		 *  6                  BPEL Identifier
		 *  7 ..               Parteners wsdl files (.wsdl) 
		 */
		//////////////////////////////////////////////////////////////////
		//Remove the /* and */  to enable debug messages
		
		WorkWSDLPrint(args[2]);
		
		ReadBpelPrint(args[1]);
		
		WorkWSDLPrint(args[7]);
		
		String szGenerationType=args[0];
		String szBpelFilename=args[1];
		String szBpelWSDL=args[2];
		String szPartenerWSDL=args[7];
		String szNamespace=args[3];
		String szMainJarFile=args[4];
		String szCompositionName=args[5];
		String szCompositionNameBPEL=args[6];
		Writer output = null;
		String newLine = System.getProperty("line.separator");

		/////////////////////////////////////////////////////////////////////////////////////////////
		// Generate bpel/process jbi.xml file
		if ((szGenerationType.equalsIgnoreCase("0")) ||(szGenerationType.equalsIgnoreCase("2")))
		{
			File file = new File("jbi.xml");
		    try {
				output = new BufferedWriter(new FileWriter(file));
				output.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
				output.write(newLine);
			    output.write("<jbi ");
			    output.write(newLine);
			    output.write("xmlns=\"http://java.sun.com/xml/ns/jbi\"");
			    output.write(newLine);
			    output.write("xmlns:ns0=\"");
			    output.write(szNamespace);
			    output.write("\"");
			    output.write(newLine);
			    output.write("xmlns:ns1=\"");
			    output.write(WSDLGetPortNS(szPartenerWSDL));
			    output.write("\"");
			    output.write(newLine);
			    output.write("xmlns:ns2=\"");
			    output.write(WSDLGetPortNS(szBpelWSDL));
			    output.write("\"");
			    
			    
			    output.write(" version=\"1.0\">");
			    
			    output.write(newLine);
			    output.write("<services binding-component=\"false\">");
			    for (int i=0;i<GetBPELMaximumPartnersLinks(szBpelFilename);i++)
			    {
			    	String sName=GetBpelName(szBpelFilename,i);
			    	String sMyRole=GetBpelMyRole(szBpelFilename,i);
			    	String sPRole=GetBpelPartenerRole(szBpelFilename,i);
			    	if (sPRole==null)
			    	{
			    		output.write(newLine);
			    		output.write("<provides");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sMyRole);
			    		output.write("_myRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		output.write("interface-name=\"ns2:");
			    		output.write(WSDLGetPort(szBpelWSDL));
			   		 	output.write("\"");
			   		 	output.write(newLine);
			   		 	output.write("service-name=\"ns0:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			    	}else
			    	{
			    		output.write(newLine);
			    		output.write("<consumes");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sPRole);
			    		output.write("_partnerRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		output.write("interface-name=\"ns1:");
			    		output.write(WSDLGetPort(szPartenerWSDL));
			   		 	output.write("\"");
			   		 	output.write(newLine);
			   		 	output.write("service-name=\"ns0:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			    	}
			    }
			    
			    output.write(newLine);
			    output.write("</services>");
			    output.write(newLine);
			    output.write("</jbi>");
			    
			    output.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
		
		/////////////////////////////////////////////////////////////////////////////////////////////
		// Generate composition xml file
		if ((szGenerationType.equalsIgnoreCase("1")) ||(szGenerationType.equalsIgnoreCase("2")))
		{
			File file = new File(szCompositionName+".xml");
		    try {
				output = new BufferedWriter(new FileWriter(file));
				output.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
				output.write(newLine);
			    output.write("<jbi ");
			    output.write(newLine);
			    output.write("xmlns=\"http://java.sun.com/xml/ns/jbi\"");
			    output.write(newLine);
			    output.write("xmlns:ns2=\"");
			    output.write(szNamespace);
			    output.write("\"");
			    output.write(newLine);
			    output.write("xmlns:ns3=\"");
			    output.write(WSDLGetPortNS(szPartenerWSDL));
			    output.write("\"");
			    output.write(newLine);
			    output.write("xmlns:ns1=\"");
			    output.write(WSDLGetPortNS(szBpelWSDL));
			    output.write("\"");
			    
			    
				output.write(" version=\"1.0\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/jbi ./jbi.xsd\" >");
				
				output.write(newLine);
				output.write("<service-assembly>");
				output.write(newLine);
				output.write("<identification>");
				output.write(newLine);
				output.write("<name>");
				output.write(szCompositionName);
				output.write("</name>");
				output.write(newLine);
				output.write("<description>Represents the Service Assembly of LoginComposition</description>");
				output.write(newLine);
				output.write("</identification>");
				output.write(newLine);
				output.write("<service-unit>");
				output.write(newLine);
				output.write("<identification>");
				output.write(newLine);
				output.write("<name>");
				output.write(szCompositionNameBPEL);
				output.write("</name>");
				output.write(newLine);
				output.write("<description>Represents this Service Unit</description>");
				output.write(newLine);
				output.write("</identification>");
				output.write(newLine);
				output.write("<target>");
				output.write(newLine);
				output.write("<artifacts-zip>");
				output.write(szMainJarFile);
				output.write("</artifacts-zip>");
				output.write(newLine);
				output.write("<component-name>sun-bpel-engine</component-name>");
				output.write(newLine);
				output.write("</target>");
				output.write(newLine);
				output.write("</service-unit>");
				output.write(newLine);
				output.write("<service-unit>");
				output.write(newLine);
				output.write("    <identification>");
				output.write(newLine);
				output.write("<name>");
				output.write(szCompositionName);
				output.write("-sun-http-binding</name>");
				output.write(newLine);
				output.write("<description>Represents this Service Unit</description>");
				output.write(newLine);
				output.write("</identification>");
				output.write(newLine);
				output.write("<target>");
				output.write(newLine);
				output.write("<artifacts-zip>sun-http-binding.jar</artifacts-zip>");
				output.write(newLine);
				output.write("<component-name>sun-http-binding</component-name>");
				output.write(newLine);
				output.write("</target>");
				output.write(newLine);
				output.write("</service-unit>");
				output.write(newLine);
				output.write("<connections>");
				output.write(newLine);
				output.write("<connection>");
				output.write(newLine);
				   
			  /*    <consumer endpoint-name="loginwsdlbpelPort" service-name="ns1:loginwsdlbpelService"/>
				<provider endpoint-name="loginwsdlbpelPortTypeRole_myRole" service-name="ns2:BpelWsdl"/>
				*/
				for (int i=0;i<GetBPELMaximumPartnersLinks(szBpelFilename);i++)
			    {
			    	String sName=GetBpelName(szBpelFilename,i);
			    	String sMyRole=GetBpelMyRole(szBpelFilename,i);
			    	String sPRole=GetBpelPartenerRole(szBpelFilename,i);
			    	if (sPRole==null)
			    	{
			    		output.write(newLine);
			    		output.write("<provider");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sMyRole);
			    		output.write("_myRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		
			   		 	output.write("service-name=\"ns2:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			   		 	
			   		    output.write(newLine);
			    		output.write("<consumer");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sName);
			    		
			    		output.write("Port\"");
			    		output.write(newLine);
			    		output.write("service-name=\"ns1:");
			   		 	output.write(sName);
			   		 	output.write("Service\"/>");
			    	}
			    }
				output.write("</connection>");
				output.write(newLine);
				output.write("<connection>");
				output.write(newLine);
				   /*
				<consumer endpoint-name="UserManagerRole_partnerRole" service-name="ns2:UserManagerWS"/>
				<provider endpoint-name="UserManagerPort" service-name="ns3:UserManagerService"/>
				*/
				for (int i=0;i<GetBPELMaximumPartnersLinks(szBpelFilename);i++)
			    {
			    	String sName=GetBpelName(szBpelFilename,i);
			   // 	String sMyRole=GetBpelMyRole(szBpelFilename,i);
			    	String sPRole=GetBpelPartenerRole(szBpelFilename,i);
			    	if (sPRole==null){}else
			    	{
			    		output.write(newLine);
			    		output.write("<consumer");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sPRole);
			    		output.write("_partnerRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		
			   		 	output.write("service-name=\"ns2:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			   		 	
			   		    output.write(newLine);
			    		output.write("<provider");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sName);
			    		
			    		output.write("Port\"");
			    		output.write(newLine);
			    		output.write("service-name=\"ns3:");
			   		 	output.write(sName);
			   		 	output.write("Service\"/>");
			    	}
			    }
				/*
				 * output.write(newLine);
			    		output.write("<consumes");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sPRole);
			    		output.write("_partnerRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		output.write("interface-name=\"ns1:");
			    		output.write(WSDLGetPort(szPartenerWSDL));
			   		 	output.write("\"");
			   		 	output.write(newLine);
			   		 	output.write("service-name=\"ns0:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
				 */
				output.write("</connection>");
				output.write(newLine);
				output.write("</connections>");
				output.write(newLine);
				output.write("</service-assembly>");
		        output.write(newLine);
				output.write("<connections>");
				output.write("<connection>");
				/*
				<consumer endpoint-name="loginwsdlbpelPort" service-name="ns1:loginwsdlbpelService"/>
				<provider endpoint-name="loginwsdlbpelPortTypeRole_myRole" service-name="ns2:BpelWsdl"/>
				*/
				for (int i=0;i<GetBPELMaximumPartnersLinks(szBpelFilename);i++)
			    {
			    	String sName=GetBpelName(szBpelFilename,i);
			    	String sMyRole=GetBpelMyRole(szBpelFilename,i);
			    	String sPRole=GetBpelPartenerRole(szBpelFilename,i);
			    	if (sPRole==null)
			    	{
			    		output.write(newLine);
			    		output.write("<provider");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sMyRole);
			    		output.write("_myRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		
			   		 	output.write("service-name=\"ns2:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			   		 	
			   		    output.write(newLine);
			    		output.write("<consumer");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sName);
			    		
			    		output.write("Port\"");
			    		output.write(newLine);
			    		output.write("service-name=\"ns1:");
			   		 	output.write(sName);
			   		 	output.write("Service\"/>");
			    	}
			    }
				output.write("</connection>");
				output.write("<connection>");
				/*<consumer endpoint-name="UserManagerRole_partnerRole" service-name="ns2:UserManagerWS"/>
				<provider endpoint-name="UserManagerPort" service-name="ns3:UserManagerService"/>*/
				for (int i=0;i<GetBPELMaximumPartnersLinks(szBpelFilename);i++)
			    {
			    	String sName=GetBpelName(szBpelFilename,i);
			    	//String sMyRole=GetBpelMyRole(szBpelFilename,i);
			    	String sPRole=GetBpelPartenerRole(szBpelFilename,i);
			    	if (sPRole==null){}else
			    	{
			    		output.write(newLine);
			    		output.write("<consumer");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sPRole);
			    		output.write("_partnerRole");
			    		output.write("\"");
			    		output.write(newLine);
			    		
			   		 	output.write("service-name=\"ns2:");
			   		 	output.write(sName);
			   		 	output.write("\"/>");
			   		 	
			   		    output.write(newLine);
			    		output.write("<provider");
			    		output.write(newLine);
			    		output.write("endpoint-name=\"");
			    		output.write(sName);
			    		
			    		output.write("Port\"");
			    		output.write(newLine);
			    		output.write("service-name=\"ns3:");
			   		 	output.write(sName);
			   		 	output.write("Service\"/>");
			    	}
			    }
				output.write("</connection>");
				output.write("</connections>");
				output.write("</service-assembly>");
				output.write("</jbi>");		    
			    	    
			    output.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
			
	}

}
