/*******************************************************************************
 * 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.runtime.IStatus;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
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.axis.consumption.ui.util.WSDLUtils;
import org.eclipse.jst.ws.internal.common.EnvironmentUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.command.common.BuildProjectCommand;
import org.eclipse.wst.command.internal.provisional.env.core.common.SimpleStatus;
import org.eclipse.wst.command.internal.provisional.env.core.common.Status;
import org.eclipse.wst.ws.internal.parser.discovery.WebServicesParserExt;
import org.eclipse.wst.ws.internal.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(ProjectUtilities.getProject(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;
    }
    
  }
}
