/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.axis.consumption.ui.command;

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

import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.namespace.QName;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jst.j2ee.internal.webservices.WebServiceClientGenerator;
import org.eclipse.jst.j2ee.internal.webservices.WebServicesClientDataHelper;
import org.eclipse.jst.ws.internal.axis.consumption.core.command.WSDL2JavaCommand;
import org.eclipse.jst.ws.internal.axis.consumption.ui.env.J2EEEnvironment;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.AddJarsToProjectBuildPathTask;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.CopyAxisJarCommand;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.DefaultsForHTTPBasicAuthCommand;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.RefreshProjectCommand;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.Stub2BeanCommand;
import org.eclipse.jst.ws.internal.axis.consumption.ui.task.ValidateWSDLCommand;
import org.eclipse.jst.ws.internal.common.EnvironmentUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.common.StringToIProjectTransformer;
import org.eclipse.jst.ws.internal.consumption.command.common.BuildProjectCommand;
import org.eclipse.jst.ws.internal.consumption.util.WSDLUtils;
import org.eclipse.wst.command.env.core.common.SimpleStatus;
import org.eclipse.wst.command.env.core.common.Status;
import org.eclipse.wst.ws.parser.discovery.WebServicesParserExt;
import org.eclipse.wst.ws.parser.wsil.WebServicesParser;

/**
 * 
 */
public class AxisClientGenerator extends WebServiceClientGenerator 
{
  private String pluginId_ = "org.eclipse.jst.ws.axis.consumption.ui";
  
  public IStatus genWebServiceClientArtifacts(WebServicesClientDataHelper dataModel)
  {
  	//get info from the model
  	String wsdlURL = dataModel.getWSDLUrl();
    String project = dataModel.getProjectName();
    String outputWSDLFilePathName = dataModel.getOutputWSDLFileName();
    String serviceQName = dataModel.getServiceQName();
    boolean shouldDeploy = dataModel.shouldDeploy();
    
    
    //Generate the artifacts
    Status status = new SimpleStatus("");
    //AxisClientDefaultingCommand
    AxisClientDefaultingCommand axisClientDefaultingCommand = new AxisClientDefaultingCommand();
                                                                                                axisClientDefaultingCommand.setWsdlURL(wsdlURL);
    axisClientDefaultingCommand.setWebServicesParser(new WebServicesParserExt());
    axisClientDefaultingCommand.setClientProject((IProject)(new StringToIProjectTransformer().transform(project)));
    axisClientDefaultingCommand.setTestProxySelected(false);
    axisClientDefaultingCommand.setIsClientScenario(true);
    axisClientDefaultingCommand.setGenerateProxy(true);
    J2EEEnvironment j2eeEnvironment = new J2EEEnvironment();
    status = axisClientDefaultingCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }
    
//  Figure out if this is a Web, EJB, or AppClient project
    boolean isWebProject = ResourceUtils.isWebProject(axisClientDefaultingCommand.getClientProject());
    
    //DefaultsForHTTPBasicAuthCommand
    DefaultsForHTTPBasicAuthCommand httpCommand = new DefaultsForHTTPBasicAuthCommand();
    httpCommand.setJavaWSDLParam(axisClientDefaultingCommand.getJavaWSDLParam());
    httpCommand.setWsdlServiceURL(axisClientDefaultingCommand.getWsdlURL());
    httpCommand.setWebServicesParser(axisClientDefaultingCommand.getWebServicesParser());
    status = httpCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }
    
    //CopyAxisJarCommand
    //The code generated by the Axis WSDL2Java emitter requires axis.jar in order to compile.
    //In the case of a Web project, we add it to the lib directory.
    //In the case of an EJB or App Client project, we add it as an external JAR. This breaks
    //the team environment scenario. We will have to think of a better way to deal with this 
    //in the future.
    if (isWebProject)
    {
	    CopyAxisJarCommand axjCommand = new CopyAxisJarCommand();
	    axjCommand.setProject(axisClientDefaultingCommand.getClientProject());
	    status = axjCommand.execute(j2eeEnvironment);
	    if (status.getSeverity()!=Status.OK)
	    {
	      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
	    }
    }
    else 
    {
      AddAxisJARToBuildPathCommand addAxisCommand = new AddAxisJARToBuildPathCommand();
      addAxisCommand.setProject(axisClientDefaultingCommand.getClientProject());
      status = addAxisCommand.execute(j2eeEnvironment);
	  if (status.getSeverity() != Status.OK)
      {
        return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
      }      
    }
    
    //AddJarsToProjectBuildPathTask
    AddJarsToProjectBuildPathTask addJarsCommand = new AddJarsToProjectBuildPathTask();
    addJarsCommand.setProject(axisClientDefaultingCommand.getClientProject());
    status = addJarsCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    
    
    //DefaultsForClientJavaWSDLCommand
    DefaultsForClientJavaWSDLCommand defClientCommand = new DefaultsForClientJavaWSDLCommand();
    defClientCommand.setJavaWSDLParam(axisClientDefaultingCommand.getJavaWSDLParam());
    defClientCommand.setProxyProject(axisClientDefaultingCommand.getClientProject());
    defClientCommand.setWSDLServiceURL(axisClientDefaultingCommand.getWsdlURL());
    status = defClientCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }        
    
    //ValidateWSDLCommand
    ValidateWSDLCommand valWSDLCommand = new ValidateWSDLCommand();
    valWSDLCommand.setWsdlURI(axisClientDefaultingCommand.getWsdlURL());
    valWSDLCommand.setWebServicesParser(axisClientDefaultingCommand.getWebServicesParser());
    status = valWSDLCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    
    
    //WSDL2JavaCommand
    WSDL2JavaCommand w2jCommand = new WSDL2JavaCommand();
    w2jCommand.setJavaWSDLParam(axisClientDefaultingCommand.getJavaWSDLParam());
    w2jCommand.setWsdlURI(axisClientDefaultingCommand.getWsdlURL());
    status = w2jCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    

    //RefreshProjectCommand
    RefreshProjectCommand refreshCommand = new RefreshProjectCommand();
    refreshCommand.setProject(axisClientDefaultingCommand.getClientProject());
    status = refreshCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    
    
    Stub2BeanCommand s2bCommand = new Stub2BeanCommand();
    s2bCommand.setJavaWSDLParam(axisClientDefaultingCommand.getJavaWSDLParam());
    s2bCommand.setWebServicesParser(axisClientDefaultingCommand.getWebServicesParser());
    s2bCommand.setClientProject(axisClientDefaultingCommand.getClientProject());
    status = s2bCommand.execute(j2eeEnvironment); 
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }

    //CopyClientWSDLCommand
    CopyClientWSDLCommand copyCommand = new CopyClientWSDLCommand();
    copyCommand.setWsdlURL(axisClientDefaultingCommand.getWsdlURL());
    copyCommand.setClientWSDLPathName(outputWSDLFilePathName);
    copyCommand.setWsParser(axisClientDefaultingCommand.getWebServicesParser());
    status = copyCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    
    
    
    //BuildProjectCommand
    BuildProjectCommand buildCommand = new BuildProjectCommand();
    buildCommand.setProject(axisClientDefaultingCommand.getClientProject());
    buildCommand.setForceBuild(true);
    status = buildCommand.execute(j2eeEnvironment);
    if (status.getSeverity()!=Status.OK)
    {
      return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
    }    
        
    //Calculate the service interface and service endpoint interface names
    InterfaceNames interfaceNames = calculateSIandSEIName(axisClientDefaultingCommand.getWsdlURL(), serviceQName, axisClientDefaultingCommand.getWebServicesParser());
    String siName = interfaceNames.getSiName(); 
    String[] seiNames = interfaceNames.getSeiNames();
    if (siName==null || siName.length()==0 || seiNames==null || seiNames.length==0)
    {
      return new org.eclipse.core.runtime.Status(IStatus.ERROR,pluginId_,0,"Problems!!",null);
    }
    
    //Set info on the dataModel
    dataModel.setServiceInterfaceName(siName);
    dataModel.setServiceEndpointInterfaceNames(seiNames);
    dataModel.setDidGenDescriptors(false);
    
    return EnvironmentUtils.convertStatusToIStatus(status, pluginId_);
  }
  
  private InterfaceNames calculateSIandSEIName(String wsdlURL, String serviceQName, WebServicesParser wsParser)
  {
    InterfaceNames iNames = new InterfaceNames();
    String serviceLocalPart = serviceQName.substring(serviceQName.lastIndexOf(':')+1);
    Map pkg2nsMapping = null;
    Definition def = wsParser.getWSDLDefinition(wsdlURL);
 
    Map services = def.getServices();
    Service service = null;
    for (Iterator it = services.values().iterator(); it.hasNext();)
    {
      service = (Service)it.next();
      if (serviceLocalPart.equals(service.getQName().getLocalPart()))
        break;
    }        
      
    if (service!=null)
    {
      String servicePkgName = WSDLUtils.getPackageName(service, pkg2nsMapping);
      String serviceClassName = service.getQName().getLocalPart();
      String jndiName = serviceClassName;
      Map ports = service.getPorts();
      for (Iterator it2 = ports.values().iterator(); it2.hasNext();)
      {
        if (serviceClassName.equals(((Port)it2.next()).getBinding().getPortType().getQName().getLocalPart()))
        {
          serviceClassName = serviceClassName + "_Service";
          break;
        }
      }
      ArrayList seiNames = new ArrayList();
      for (Iterator it2 = ports.values().iterator(); it2.hasNext();)
      {
        Port port = (Port)it2.next();
        SOAPAddress soapAddress = null;
        List extensibilityElements = port.getExtensibilityElements();
        if (extensibilityElements != null)
        {
          for (Iterator it3 = extensibilityElements.iterator(); it3.hasNext();)
          {
            Object object = it3.next();
            if (object instanceof SOAPAddress)
            {
              soapAddress = (SOAPAddress)object;
              break;
            }
          }
        }
        if (soapAddress != null)
        {
          PortType portType = port.getBinding().getPortType();
          QName portTypeQName = portType.getQName();
          String portTypePkgName = WSDLUtils.getPackageName(portType, pkg2nsMapping);
          String portTypeClassName = portTypeQName.getLocalPart();
          if (jndiName.equals(portTypeClassName))
              portTypeClassName = portTypeClassName + "_Port";
          seiNames.add(portTypePkgName+"."+portTypeClassName); 
        }
      }
      iNames.setSiName(servicePkgName+"."+serviceClassName);
      iNames.setSEINames(convertToStringArray(seiNames.toArray()));
    }    
    return iNames;
  }
  
  private String[] convertToStringArray(Object[] a)
  {
  	if (a==null) return new String[0];
  	
  	int length = a.length;
  	String[] sa = new String[length];
  	for (int i=0; i<length; i++)
  	{
  		Object obj = a[i];
  		if (obj instanceof String)
  		{
  			sa[i] = (String)obj;
  		}
  	}
  	return sa;
  }  
  private class InterfaceNames
  {
    private String siName_;
    private String[] seiNames_;
    
    public String getSiName()
    {
      return siName_;
    }

    public String[] getSeiNames()
    {
      return seiNames_;
    }
    
    
    public void setSiName(String siName)
    {
      siName_ = siName;
    }
    
    public void setSEINames(String[] seiNames)
    {
      seiNames_ = seiNames;
    }
    
  }
}
