/*
 *   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package org.apache.axis.wsdl.wsdl2ws;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.xml.namespace.QName;

import org.apache.axis.wsdl.symbolTable.BaseType;
import org.apache.axis.wsdl.symbolTable.BindingEntry;
import org.apache.axis.wsdl.symbolTable.DefinedType;
import org.apache.axis.wsdl.symbolTable.SymbolTable;
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.wsdl.wsdl2ws.info.FaultInfo;
import org.apache.axis.wsdl.wsdl2ws.info.MethodInfo;
import org.apache.axis.wsdl.wsdl2ws.info.ParameterInfo;
import org.apache.axis.wsdl.wsdl2ws.info.ServiceInfo;
import org.apache.axis.wsdl.wsdl2ws.info.Type;
import org.apache.axis.wsdl.wsdl2ws.info.TypeMap;
import org.apache.axis.wsdl.wsdl2ws.info.WSDLInfo;
import org.apache.axis.wsdl.wsdl2ws.info.WebServiceContext;
import org.apache.axis.wsdl.wsdl2ws.info.WrapperInfo;

/**
 * This is the main class for the WSDL2Ws Tool. This class reuses the code in the 
 * Axis java implementations to parse the WSDL file. Here is what is done: 
 * 
 *  1) create a Symbol table by parsing WSDL file.
 *  2) create TypeMap object by iterating through types in the Symbol Table.
 *  3) create WrapperInfo object using command line arguments and SymbolTable information.
 *  4) create ServiceInfo object parsing the Symbol table.
 *  5) create WebServiceContext using above three classes and start execution 
 * 
 * @author hemapani@opensource.lk
 * @author Samisa Abeysinghe (sabeysinghe@virtusa.com)
 * @author hawkeye (hawkinsj@uk.ibm.com)
 * @author nadir amra (amra@us.ibm.com)
 */
public class WSDL2Ws
{
    public static boolean c_veryVerbose = false;
    public static boolean c_verbose = false;

    // Command line arguments
    private CLArgParser c_cmdLineArgs = null;
            
    // WSDL parser symbol table
    private SymbolTable c_symbolTable;
    
    // WSDL info.
    private WSDLInfo c_wsdlInfo;

    /**
     * Prints out usage.
     */
    public static void usage()
    {
        System.out.println(
            "java WSDL2Ws -<options> <wsdlfile>\n"
                + "-h, -help              print this message\n"
                + "-o<folder>             target output folder - default is current folder.\n"
                + "-l<c++|c>              target language (c++|c) - default is c++.\n"
                + "-s<server|client>      target side (server|client) - default is server.\n"
                + "-v,                    be verbose - will show exception stack trace when\n"
                + "                       exceptions occur.\n"
                + "-vv                    be very verbose - debug information will be shown.\n"
                + "-t<timeout>            uri resolution timeout in seconds - default\n"
                + "                       is 0 (no timeout).\n"
                + "-b<binding-name>       binding name that will be used to generate stub.\n"
                + "-w<wrapped|unwrapped>  generate wrapper style or not - default is wrapped.\n"
                + "                       In order for an operation to be eligible for\n"
                + "                       wrapper-style, the following criteria must be met:\n"
                + "                       -- There is at most one single part in input and\n"
                + "                          output messages\n"
                + "                       -- Each part definition must reference an element\n"
                + "                       -- The input element must have the same name as\n"
                + "                          the operation\n"
                + "                       -- The input and output elements have no attributes\n"
                );
    }
    
    /**
     * Main entry point. 
     * 
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception
    {
        // Kick off code generation
        WSDL2Ws gen = null;
        try
        {
            gen = new WSDL2Ws(args);
            gen.generateWrappers();
        }
        catch (Exception e)
        {
            if (c_verbose)
                e.printStackTrace();
            else if (e.getMessage() != null)
                System.out.println("\nERROR: " + e.getMessage());
            
            if (e.getMessage() != null)
                System.out.println("\nCode generation failed. Please see errors above.\n");
            
            return;
        }
        
        // Indicate code generation complete and show where stored.
        System.out.println("\nCode generation completed. Generated files in directory\n'" 
                + gen.getCmdLineArgs().getOutputDirectory() + "'.");
    }    
    
    /**
     * Gathers the parameters passed in and parses the WSDL file, generating the symbol table. 
     * 
     * @param args
     * @throws WrapperFault
     */
    public WSDL2Ws(String[] args) throws WrapperFault
    {
        try
        {
            // ==================================================
            // Process the parameters
            // ==================================================            

            // Get parameters and validate
            c_cmdLineArgs = new CLArgParser(args);
            if (!c_cmdLineArgs.areOptionsValid() 
                    || c_cmdLineArgs.isSet("h") || c_cmdLineArgs.getArgumentCount() != 1)
            {
                usage();
                return;
            }
            
            // Verbose mode?
            c_veryVerbose = c_cmdLineArgs.beVeryVerbose();
            c_verbose = c_cmdLineArgs.beVerbose();
            
            // language c or c++ - CUtils.setLanguage MUST be invoked at the very beginning!
            CUtils.setLanguage(c_cmdLineArgs.getTargetLanguage());
            
            // ==================================================
            // Parse the WSDL file
            // ==================================================
            
            c_wsdlInfo = new WSDLInfo(c_cmdLineArgs.getURIToWSDL());
            c_wsdlInfo.setVerbose(c_veryVerbose);
            c_wsdlInfo.setTimeout(c_cmdLineArgs.getTimeout()); 
            c_wsdlInfo.setNoWrapperStyle(c_cmdLineArgs.isWrapperStyle() == false);

            c_symbolTable = c_wsdlInfo.parse();
            
            // ==================================================
            // Let us do some validation on the WSDL passed in.
            // ==================================================
            
            // Maximum of one <service> tag is supported in WSDL for the time being.
            if (c_wsdlInfo.getServices().size() > 1)
                throw new WrapperFault("Multiple service definitions not supported.");
            
            // If a service definition is not defined then caller needs to specify a 
            // binding to use in order for us to generate the stubs.  Not having service definition will
            // only result in not knowing the Web service end point, so it is really not necessary.
            if (c_wsdlInfo.getServices().size() == 0 && !c_cmdLineArgs.isSet("b"))
            {
                throw new WrapperFault(
                          "Service definition not found in WSDL document. " 
                        + "A service definition must be specified in the WSDL document or " 
                        + "a binding needs to be specified using the -b option.");
            }
        }
        catch (WrapperFault e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new WrapperFault(e);
        }
    }

    /**
     * Kicks of the generation of the stub code.
     * 
     * @throws WrapperFault
     */
    public void generateWrappers() throws Exception
    {        
        // ==================================================
        // Get service, ports, binding, and port type
        // ==================================================   
        
        Port port                 = null;
        BindingEntry bindingEntry = null;
   
        //TODO  resolve this
        //  this code will generate one stub corresponding to a port.  Other ports
        //  are ignored. Should really generate one service stub per port.
        
        // If binding is specified, ensure binding is supported and see if there is a port that uses 
        // it in order to get end point. If not specified, then use the service definition to 
        // obtain the information we need.
        if (c_cmdLineArgs.isSet("b"))
        {
            // Validate binding
            bindingEntry = c_wsdlInfo.getBindEntry(c_cmdLineArgs.getBinding());
            if (bindingEntry == null)
                throw new WrapperFault("Specified binding '" + c_cmdLineArgs.getBinding() + "' not found.");
            
            if (!WSDLInfo.isSOAP11Binding(bindingEntry))
                throw new WrapperFault("Specified binding '" + c_cmdLineArgs.getBinding() + "' is not supported.");
            
            // Get port in order to obtain end point. Not having a port is OK.
            if (c_wsdlInfo.getServices().size() != 0)
                port = WSDLInfo.getPort((Service)c_wsdlInfo.getServices().get(0), bindingEntry);
        }
        else
        {
            // We first ask for SOAP 1.1 ports that have a binding style of document....if 
            // there is none, then we ask for SOAP 1.1 ports that have a binding style of rpc.
            Service service = (Service)c_wsdlInfo.getServices().get(0);
            ArrayList servicePorts = c_wsdlInfo.getPortsSOAP11Document(service);
            if (servicePorts.isEmpty())
                servicePorts = c_wsdlInfo.getPortsSOAP11RPC(service);
            if (servicePorts.isEmpty())
                throw new WrapperFault("A port with a supported binding was not found. Ensure SOAP 1.1 XML namespace is used. ");
    
            port            = (Port)servicePorts.get(0);
            bindingEntry    = c_symbolTable.getBindingEntry(port.getBinding().getQName());
        }
        
        // Ensure that binding entry is document/literal or RPC encoded since that is all that is supported.
        if (bindingEntry != null)
        {
            String style = bindingEntry.getBindingStyle().getName();
            if (style == null)
                style = "document";

            if ((style.equals("document") && !bindingEntry.hasLiteral())
                    || (style.equals("rpc") && bindingEntry.hasLiteral()))
                throw new WrapperFault("Binding style not supported.  Supported binding styles: document/literal, rpc/encoded");
            
            // If C-stubs currently supports document/literal only
            if (style.equals("rpc") && c_cmdLineArgs.getTargetLanguage().equalsIgnoreCase("c"))
                throw new WrapperFault("Cannot generate C stubs for rpc/encoded.");
        }
        
        // ==================================================
        // Build the context that is needed by the code generators.
        // ==================================================            
                       
        // Wrapper info
        WrapperInfo wrapperInfo = 
            new WrapperInfo(bindingEntry.getBindingStyle().getName(), 
                            CUtils.getLanguage(), 
                            c_cmdLineArgs.getOutputDirectory(), 
                            c_cmdLineArgs.getTargetEngine(),
                            c_wsdlInfo.getTargetNameSpaceOfWSDL());
        
        // Service info
        boolean userRequestedWSDLWrappingStyle = c_cmdLineArgs.isSet("w") && c_cmdLineArgs.isWrapperStyle();
        String serviceName       = WSDLInfo.getServiceName(bindingEntry);
        ArrayList serviceMethods = c_wsdlInfo.processServiceMethods(bindingEntry, 
                                                                    c_cmdLineArgs.isWrapperStyle(), 
                                                                    userRequestedWSDLWrappingStyle);
        ServiceInfo serviceInfo  = new ServiceInfo(serviceName, serviceMethods, WSDLInfo.getTargetEndPointURI(port));
        
        // Context
        WebServiceContext wsContext = new WebServiceContext(wrapperInfo, serviceInfo, c_wsdlInfo.getTypeMap()); 
        
        // Generator
        WebServiceGenerator wsg = WebServiceGeneratorFactory.createWebServiceGenerator(wsContext);
        
        // ==================================================
        // Determine which types to externalize.
        // ==================================================    
        
        // There must be a better way to do this
        exposeReferenceTypes(wsContext);
        exposeMessagePartsThatAreAnonymousTypes(wsContext);
        // This call must be last one called of the exposexxx methods!
        exposeNestedTypesThatAreAnonymousTypes(wsContext);
        
        // Dump the map if requested.
        if (c_veryVerbose)
            c_wsdlInfo.getTypeMap().dump();
        
        // ==================================================
        // Generate the artifacts
        // ================================================== 
        
        // Generate code
        wsg.generate();
    }    
    
    // The following 3 exposeXXX methods attempts to expose anonymous types so that 
    // the types are externalized to the user.  
    
    /**
     * This method goes through the types and for any types that are referenced works out whether
     * they need to be exposed as a seperate class.
     * If they do require to be a seperate class then the name of the type will be changed from 
     * ">nameoftype" to "nameoftype". This will then get picked up later on in the process and the
     * type will be exposed as a seperate class. 
     * 
     * @param wsContext the webservice context.
     */
    private void exposeReferenceTypes(WebServiceContext wsContext)
    {
        // get the main types
        Collection types = c_symbolTable.getTypeIndex().values();
        Iterator typeIterator = types.iterator();   
        while(typeIterator.hasNext())
        {
            Object highLevelType = typeIterator.next();
            if(!(highLevelType instanceof BaseType))
            {
                DefinedType type = (DefinedType)highLevelType;
                
                if(!type.getQName().getLocalPart().toString().startsWith(">"))
                {
                    // It's not an "inner" type so look for the refs (this might not be valid 
                    // logic and refs might be acceptable for these types too !)
                    HashSet nestedTypes = type.getNestedTypes(c_symbolTable, true);
                    Iterator nestTypeIter = nestedTypes.iterator();
                    while(nestTypeIter.hasNext())
                    {
                        Object nestedType =nestTypeIter.next();
                        if(!(nestedType instanceof BaseType))
                        {
                            TypeEntry defType = (TypeEntry)nestedType;

                            TypeEntry referencedType =defType.getRefType(); 
                            if (referencedType==null)
                                continue;
                            
                            if(c_veryVerbose)
                                System.out.println( "EXPOSE1: Checking whether to expose ref-types for "+defType.getQName().getLocalPart());

                            // If ref type is anonymous and thus currently not exposed because 
                            // it's an "inner" type, expose it and any nested types (latter is TODO).                            
                            
                            if(referencedType.getQName().getLocalPart().startsWith(">") 
                                    && referencedType.getQName().getLocalPart().lastIndexOf(">") == 0)
                            {
                                if(c_veryVerbose)
                                    System.out.println( "EXPOSE1: Exposing ref-type "+referencedType.getQName());

                                Type innerClassType = wsContext.getTypemap().getType(referencedType.getQName());
                                
                                String newLocalPart =  new QName(defType.getQName().getLocalPart()).toString();
                                innerClassType.externalize(new QName(innerClassType.getName().getNamespaceURI(), newLocalPart));
                            }
                        }
                    }
                }
                
            }
        }
    }
    
    /**
     * This method attempts to find anonymous types in the parameter list of 
     * web-service methods to determine if the type should be exposed.
     * @param wsContext
     */
    private void exposeMessagePartsThatAreAnonymousTypes(WebServiceContext wsContext)
    {
        // get the main types
        Collection types = c_symbolTable.getTypeIndex().values();
        Iterator typeIterator = types.iterator();   
        while(typeIterator.hasNext())
        {
            Object highLevelType = typeIterator.next();
            if(!(highLevelType instanceof BaseType))
            {
                DefinedType type = (DefinedType)highLevelType;
                if(type.getQName().getLocalPart().toString().startsWith(">"))
                {
                    if(c_veryVerbose)
                        System.out.println( "EXPOSE2: Checking whether to expose anon type "+type.getQName().getLocalPart());
                    
                    // this is an "inner" type that will not be exposed
                    // however, it needs to be if it is referenced in a message part.
                    // check all the messages
                    ArrayList methods = wsContext.getServiceInfo().getMethods();
                    for(int i=0; i<methods.size(); i++)
                    {
                          MethodInfo method = (MethodInfo)methods.get(i);
                          
                          // Check for faults that need to be externalized
                          Collection faultTypes = method.getFaultType();
                          Iterator faultIterator = faultTypes.iterator();
                          while(faultIterator.hasNext())
                          {
                              FaultInfo faultType = (FaultInfo)faultIterator.next();
                              Collection parameterTypes = faultType.getParams();
                              Iterator paramIterator = parameterTypes.iterator();
                              while(paramIterator.hasNext())
                              {
                                  ParameterInfo parameterInfo =(ParameterInfo)paramIterator.next();
                                  Type parameterType = parameterInfo.getType();

                                  if(c_veryVerbose)
                                      System.out.println( "EXPOSE2: Exposing fault type "+parameterType.getName());
                                  externalizeTypeAndUpdateTypeMap(wsContext, parameterType);
                              }                              
                          }

                          // Check input parameters
                          Collection inputParameterTypes = method.getInputParameterTypes();
                          Iterator paramIterator = inputParameterTypes.iterator();
                          while(paramIterator.hasNext())
                          {
                              ParameterInfo parameterInfo =(ParameterInfo)paramIterator.next();
                              Type parameterType = parameterInfo.getType();
                              if(parameterType.getName().equals(type.getQName()))
                              {
                                  if(c_veryVerbose)
                                      System.out.println( "EXPOSE2: Matches input parm, exposing anon type "+parameterType.getName());
                                  externalizeTypeAndUpdateTypeMap(wsContext, parameterType);
                              }
                          }
                          
                          // Check output parameters
                          Collection outputParameterTypes = method.getOutputParameterTypes();
                          paramIterator = outputParameterTypes.iterator();
                          while(paramIterator.hasNext())
                          {
                              ParameterInfo parameterInfo =(ParameterInfo)paramIterator.next();
                              Type parameterType = parameterInfo.getType();
                              if(parameterType.getName().equals(type.getQName()))
                              {
                                  if(c_veryVerbose)
                                      System.out.println( "EXPOSE2: Matches output parm, exposing anon type "+parameterType.getName());                             
                                  externalizeTypeAndUpdateTypeMap(wsContext, parameterType);
                              }
                          }
                    }
                }
            }
        }
    }
    
    /**
     * 
     * @param theOrigMap
     * @param theType
     * @param nameMapper
     */
    private void exposeRelatedTypes(TypeMap theOrigMap, Type theType, Hashtable nameMapper)
    {
        QName oldName = theType.getName();                              
        Type classType =  theOrigMap.getType(oldName);
        if (classType != null && !classType.isExternalized())
        {
            if(c_veryVerbose)
                System.out.println("\nEXPOSE4: Externalizing type " + oldName);
            
            // Externalize the type - if anonymous we have to change to name
            if (classType.isAnonymous())
            {
                QName newName   =  new QName(oldName.getNamespaceURI(), 
                                             classType.getLanguageSpecificName());
    
                classType.externalize(newName);
                
                // add old name to new name mapping to name mapper hash table
                nameMapper.put(oldName, newName);
            }
            else
                classType.externalize(true);

            // Now check to see related types of this type - recursively.
            Iterator relatedTypesIt = theType.getRelatedTypes();
            Type relatedType;
            while (relatedTypesIt.hasNext())
            {
                relatedType = (Type) relatedTypesIt.next();
                if (!relatedType.isExternalized())
                    exposeRelatedTypes(theOrigMap, relatedType, nameMapper);
            }            
        }
    }
    
    /**
     * 
     * @param wsContext
     */
    private void exposeNestedTypesThatAreAnonymousTypes(WebServiceContext wsContext)
    {
        // Go through the externalized types in the typemap and externalize the 
        // related types used by each externalized type. In order to complete the externalization,
        // we need to remove the entry from the typemap and replace it with a new name.  
        // However, this will have to be done after we have iterated through the typemap since
        // updating the typemap as we iterate through it will result in an exception.
        // So we have a hash table to map old names to new names for those types that have been 
        // externalized.
        Hashtable nameMapper = new Hashtable();
        Iterator typesIt = wsContext.getTypemap().getTypes().iterator();
        Type type;
        while (typesIt.hasNext())
        {
            type = (Type) typesIt.next();
            if (type.isExternalized())
            {
                if(c_veryVerbose)
                    System.out.println("\nEXPOSE3: Checking related types for type " + type.getName());
                
                Iterator relatedTypesIt = type.getRelatedTypes();
                Type relatedType;
                while (relatedTypesIt.hasNext())
                {
                    relatedType = (Type) relatedTypesIt.next();
                    if (!relatedType.isExternalized())
                        exposeRelatedTypes(wsContext.getTypemap(), relatedType, nameMapper);
                }
            }              
        }
        
        // Now update the typemap, replacing old names with new names, using the hash table that
        // maps old names to new names.
        QName oldName;
        QName newName;
        
        for (Enumeration e = nameMapper.keys(); e.hasMoreElements() ;)
        {
            oldName = (QName) e.nextElement();
            newName = (QName) nameMapper.get(oldName);
            type    = wsContext.getTypemap().getType(oldName);
            if (type != null)
            {
                wsContext.getTypemap().removeType(oldName);
                wsContext.getTypemap().addType(newName, type);                
            }
        }
    }

    /**
     * 
     * @param wsContext
     * @param parameterType
     */
    private void externalizeTypeAndUpdateTypeMap(WebServiceContext wsContext, Type parameterType)
    {
        QName oldName = parameterType.getName();
        Type innerClassType =  wsContext.getTypemap().getType(oldName);
        if (innerClassType != null && !innerClassType.isExternalized())
        {
            QName newTypeName   =  new QName(parameterType.getName().getNamespaceURI(), 
                                             parameterType.getLanguageSpecificName());

            innerClassType.externalize(newTypeName);
            
            // Update the typemap with new info
            wsContext.getTypemap().removeType(oldName);
            wsContext.getTypemap().addType(newTypeName, innerClassType);
        }
    }
    
    /**
     * Return command line arguments. 
     * 
     * @return c_cmdLineArgs
     */
    private CLArgParser getCmdLineArgs()
    {
        return c_cmdLineArgs;
    }
}
