package lsdis;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

import org.apache.woden.WSDLException;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.wsdl20.Description;
import org.apache.woden.wsdl20.ElementDeclaration;
import org.apache.woden.wsdl20.Endpoint;
import org.apache.woden.wsdl20.InterfaceMessageReference;
import org.apache.woden.wsdl20.InterfaceOperation;
import org.apache.woden.wsdl20.Service;
import org.apache.woden.wsdl20.Interface;
import org.apache.woden.wsdl20.extensions.rpc.Direction;
import org.apache.woden.wsdl20.xml.DescriptionElement;
import org.apache.ws.commons.schema.XmlSchemaAll;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaGroupBase;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.w3c.dom.NamedNodeMap;

import  java.net.URI;

import javax.xml.namespace.QName;

public class WSDLParserDriver {

	private List<InterfaceOperation> completeMethodList = new ArrayList<InterfaceOperation>();
	private  List<String> url = new ArrayList<String>();
	private List<String> paramList = new ArrayList<String>();
	private List<String> paramTypeList = new ArrayList<String>();
	
	 
	 public List<InterfaceOperation> getCompleteMethodList() {
		return completeMethodList;
	 }

	public List<String> getUrl() {
		return url;
	 }
	
	public List<String> getParamList() {
		return paramList;
	 }
	public List<String> getParamTypeList() {
		return paramTypeList;
	 }

	public static void main(String[] args) {
		 /*Scanner keyboard = new Scanner(System.in);  
		
		 System.out.println("Enter the wsdl url: ");
		 String wsdlurl = keyboard.next();*/
		WSDLParserDriver a = new WSDLParserDriver();
		a.parse("/home/ganjoo/parser/bookstore-sample/booklist.wsdl");
		for(InterfaceOperation oper:a.getCompleteMethodList()){
		a.getParameters(oper);
		}
	}

	public void parse(String wsdlurl){
		
		try {   
		    
			WSDLFactory factory;
		    factory = WSDLFactory.newInstance();
		    WSDLReader reader = factory.newWSDLReader();
	        reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
	        Description desc = reader.readWSDL(wsdlurl);       
	        Service[] services = desc.getServices();
	        for(int i=0;i<services.length;i++){
	        	Endpoint[] endpoints = services[i].getEndpoints();
	        	boolean foundRestBinding = false;
	        	int count=0;
	        	while(count<endpoints.length){
	        		foundRestBinding = endpoints[count].getBinding().getType().equals(new URI("http://www.w3.org/ns/wsdl/http"));
	        		count++;
	        	
	        	if(foundRestBinding){
	        		System.out.println("-----------------REST Web services--------------");
	        		URI address = endpoints[count-1].getAddress();
	        		String serviceName = services[i].getName().getLocalPart();
	        		System.out.println("Service Name : " + serviceName + "\t address : " + address);
	        		Interface intrfce  = services[i].getInterface();
	        		InterfaceOperation[] intrfceOpers = intrfce.getAllInterfaceOperations();
	        		for(int j=0;j<intrfceOpers.length;j++){
	        			InterfaceOperation oper = intrfceOpers[j];
	        			String operName = oper.getName().getLocalPart();
	        			System.out.println("\t operation name " + j + ": " + operName);
	        			completeMethodList.add(oper);
	        			url.add(address.toString());
	        		
	        			
	        			
	        		}
	        	}
	        }
	        }
	        
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void getParameters(String operName){
		try{
			InterfaceOperation oper = null;
			for(InterfaceOperation oper1 :getCompleteMethodList()){
				if(oper1.getName().getLocalPart().equals(operName))
				{
					oper = oper1;
					break;
				}
				
			}
			if(oper==null){
				System.out.println("Wrong method name passed in getParameters() method");
				System.exit(0);
			}
			
			InterfaceMessageReference[] messageRefs = oper.getInterfaceMessageReferences();
			for(int k=0;k<messageRefs.length;k++){
				if(messageRefs[k].getDirection().toString().equals("in")){
					
					ElementDeclaration ed = messageRefs[k].getElementDeclaration();
					String inputMessageName = ed.getName().getLocalPart();
					
					if(ed.getContentModel().equalsIgnoreCase("org.w3c.dom")){
						org.w3c.dom.Element element = (org.w3c.dom.Element) ed.getContent();
						if(element.hasChildNodes()){
							System.out.println("Element has child nodes");
							org.w3c.dom.NodeList nl = element.getChildNodes();
							
						}
						if(element.hasAttributes()){
							System.out.println("Element has attributes");
							NamedNodeMap nodeMap = element.getAttributes();
							
						}
					}
					else if(ed.getContentModel().equalsIgnoreCase("org.apache.ws.commons.schema")){
						org.apache.ws.commons.schema.XmlSchemaElement element = (org.apache.ws.commons.schema.XmlSchemaElement ) ed.getContent();
						System.out.println("element: " + element);
						if(element != null){
							String targetNamespace = element.getQName().getNamespaceURI();
				            QName bodyFirstChildQName;
				            if (targetNamespace != null && !"".equals(targetNamespace)) {
				                bodyFirstChildQName = new QName(targetNamespace, element.getName());
				            } else {
				                bodyFirstChildQName = new QName(element.getName());
				            }
				            if(oper.getStyle()[0].equals(new URI("http://www.w3.org/ns/wsdl/style/iri"))){
				            	XmlSchemaType schemaType = element.getSchemaType();
				                if (schemaType instanceof XmlSchemaComplexType) {
				                    XmlSchemaComplexType complexType = ((XmlSchemaComplexType) schemaType);
				                    XmlSchemaParticle particle = complexType.getParticle();
				                    if (particle instanceof XmlSchemaSequence || particle instanceof XmlSchemaAll) {
				                        XmlSchemaGroupBase xmlSchemaGroupBase = (XmlSchemaGroupBase) particle;
				                        Iterator iterator = xmlSchemaGroupBase.getItems().getIterator();
				                        while (iterator.hasNext()) {
				                            XmlSchemaElement innerElement = (XmlSchemaElement) iterator.next();
				                            QName qName = innerElement.getQName();
				                            if (qName ==null && innerElement.getSchemaTypeName().equals(org.apache.ws.commons.schema.constants.Constants.XSD_ANYTYPE)) {
				                            	System.out.println("create soap message without schema and break");
				                            	break;
				                            }
				                            long minOccurs = innerElement.getMinOccurs();
				                            boolean nillable = innerElement.isNillable();
				                            
				                            String name =
				                                    qName != null ? qName.getLocalPart() : innerElement.getName();
				                            System.out.println("Name of parameter is :" + name);
				                            paramList.add(name);
				                            System.out.println("Type of Parameter is :"+innerElement.getSchemaTypeName().getLocalPart()+"\n");
				                            paramTypeList.add(innerElement.getSchemaTypeName().getLocalPart());
				                        }
				                            	

				            }
				           
				          }

						}
											   
					}else{
						System.out.println("element is null");
					}
					
				
				}
			}
		}
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

}
