/*******************************************************************************
 * Copyright (c) 2003, 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.core.command;


import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ResourceBundle;
import org.apache.axis.AxisEngine;
import org.apache.axis.server.AxisServer;
import org.apache.axis.tools.ant.axis.AdminClientTask;
import org.apache.axis.utils.ClassUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.ws.internal.axis.consumption.core.common.JavaWSDLParameter;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.wst.command.internal.env.core.common.ProgressUtils;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;

/**
 * Commands are executable, undoable, redoable objects. Every Command has a name and a description.
 */

public class GeronimoAxisDeployCommand extends AbstractDataModelOperation
{

  private JavaWSDLParameter javaWSDLParam;
  private ResourceBundle resource = ResourceBundle.getBundle("org.eclipse.jst.ws.axis.consumption.core.consumption"); //$NON-NLS-1$

  private String projectName_;
  private static final String AXIS_SERVER_CONFIG_FILE = "axis.ServerConfigFile";
  
  IFolder outputRoot;
  
  /**
   * Constructor for GeronimoAxisDeployCommand.
 * @param String projectName
   * 
   */
  public GeronimoAxisDeployCommand(String projectName)
  {
  }
  
  public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable )
  {
	IEnvironment environment = getEnvironment();
    if (javaWSDLParam == null)
    {
      return StatusUtils.errorStatus(getMessage("MSG_ERROR_JAVA_WSDL_PARAM_NOT_SET"));
    }

    if (javaWSDLParam.getProjectURL() == null || javaWSDLParam.getProjectURL().equals(""))
    { //$NON-NLS-1$
      return StatusUtils.errorStatus(getMessage("MSG_ERROR_PROJECT_URL_PARAM_NOT_SET"));
    }

    if (javaWSDLParam.getDeploymentFiles() == null || javaWSDLParam.getDeploymentFiles().length == 0)
    {
      return StatusUtils.errorStatus(
      getMessage("MSG_ERROR_DEPLOY_FILE_PARAM_NOT_SET"));
    }

    ProgressUtils.report(monitor, getMessage("MSG_AXIS_DEPLOY"));

    IStatus status = executeAdminTask();
    if (status.getSeverity() == Status.ERROR)
    {
        environment.getStatusHandler().reportError(status);
    }    
    
    status = executeAntTask();
    if (status.getSeverity() == Status.ERROR)
    {
        environment.getStatusHandler().reportError(status);
    }    
    return status;
  }
  
  protected IStatus executeAntTask()
  {
    final class DeployTask extends AdminClientTask
    {
      public DeployTask()
      {
        super.setProject(new Project());
		super.getProject().init();
		super.setTaskType("axis"); //$NON-NLS-1$
		super.setTaskName("axis-admin"); //$NON-NLS-1$
		super.setOwningTarget(new Target());
      }
    }

    DeployTask adminClient = new DeployTask();
    String url = javaWSDLParam.getProjectURL() + AxisDeployCommand.SERVICE_EXT;
    adminClient.setUrl(url);
    adminClient.setXmlFile(new File(javaWSDLParam.getDeploymentFiles()[0]));

    // Since the admin server may not be available right away we will try
    // several times to execute it.
    try
    {
      BuildException lastException = null;
      
      for( int index = 0; index < 20; index++ )
      {
        try
        {
          lastException = null;
          adminClient.execute();
        }
        catch( BuildException exc )
        {
          lastException = exc;
          
          try
          {
            Thread.sleep( 200 );
          }
          catch( InterruptedException threadException  )
          {
          }
        }
        
        // If no exception occured then we should break out of the loop.
        if( lastException == null ) break;
      }
      
      // If after many tries we still get an exception, then we will re throw it.
      if( lastException != null ) throw lastException;
    }
    catch (BuildException e)
    {
      e.printStackTrace();
      String message = e.getMessage();
      if (e.getCause() != null)
      {
        message = e.getCause().toString();
      }
      
//      Status[] childStatus = new Status[1];
//      childStatus[0] = new SimpleStatus("AxisDeployCommand", message, Status.ERROR);
//      return new SimpleStatus("AxisDeployCommand", //$NON-NLS-1$
//      getMessage("MSG_ERROR_AXIS_DEPLOY"), childStatus);
//    }
//    return new SimpleStatus("AxisDeployCommand", //$NON-NLS-1$
//    getMessage("MSG_AXIS_DEPLOY_OK"), Status.OK);
      IStatus[] childStatus = new Status[1];
      childStatus[0] = StatusUtils.errorStatus( message);
      return StatusUtils.multiStatus(getMessage("MSG_ERROR_AXIS_DEPLOY"), childStatus);
    }
    return Status.OK_STATUS; 

  }
  
  protected IStatus executeAdminTask(){
    
    IStatus status = Status.OK_STATUS;
    // check if server-config.wsdd exists
    IVirtualComponent component = J2EEUtils.getVirtualComponent( projectName_ );
    outputRoot = J2EEUtils.getOutputContainerRoot( component );
    IPath path = new Path( "WEB-INF" ).append( "server-config.wsdd" );    
    IFile descriptorFile = outputRoot.getFile( path );
    
    if (!descriptorFile.exists()){
      status = createServerConfigFile();
      if (status.getSeverity()==Status.ERROR)
        return status;
    }
    
    // check if deploy.wsdd exists
    String deployWSDD = javaWSDLParam.getDeploymentFiles()[0];
    File deployFile = new File(deployWSDD);
    if (deployFile==null || !deployFile.exists()){
      return status;
    }
    
    try {
      // get Classpath
      String jarsCP = new String();
      // classes dir
      IPath classesPath = new Path("WEB-INF").append("classes");
      IFile classesDir = outputRoot.getFile(classesPath);
      jarsCP = "\""+classesDir.getRawLocation().toOSString()+"\"";
      
      // lib JARs
      IPath libPath = new Path("WEB-INF").append("lib");
      IFile libEntry = outputRoot.getFile(libPath);
      IFolder libFolder = (IFolder)ResourceUtils.findResource(libEntry.getFullPath());
      IResource[] JARfiles = libFolder.members();
      for (int i=0;i<JARfiles.length;i++){
        IResource res = JARfiles[i];
        if (res.getFileExtension().equals("jar")){
          jarsCP = jarsCP + ";\""+ res.getRawLocation().toOSString()+"\"";
        }
      }

      // form and run utils.Admin command
      String adminCommand = new String("java -Daxis.ServerConfigFile="+ descriptorFile.getRawLocation().toOSString() 
          +" -cp "+jarsCP+" org.apache.axis.utils.Admin server "+deployFile.getCanonicalPath());
      Runtime.getRuntime().exec(adminCommand);

    }
    catch(Exception e){
      System.setProperty(AXIS_SERVER_CONFIG_FILE,"server-conifg.wsdd");      
      e.printStackTrace();
      String message = e.getMessage();
      if (e.getCause() != null)
      {
        message = e.getCause().toString();
      }
      
      IStatus[] childStatus = new Status[1];
      childStatus[0] = StatusUtils.errorStatus( message);
      return StatusUtils.multiStatus(getMessage("MSG_ERROR_AXIS_DEPLOY"), childStatus);
    }
    
    return status;
  }
  
  /**t
   * Creates the initial server-config.wsdd file from a template in Axis
   * @return
   */
  private IStatus createServerConfigFile(){
    try{

      // server-config.wsdd file
      IPath             path           = new Path( "WEB-INF" ).append( "server-config.wsdd" );    
      IFile             descriptorFile = outputRoot.getFile( path );      

      // create the initial server-config.wsdd file
      AxisEngine preEngine = new AxisServer();
      InputStream is = ClassUtils.getResourceAsStream(preEngine.getClass(), "server-config.wsdd");
      FileOutputStream fos = new FileOutputStream(descriptorFile.getRawLocation().toOSString());
      ResourceUtils.copyStream(is, fos);
      fos.close();
      
      return Status.OK_STATUS;
    }
    catch(Exception e){
      e.printStackTrace();
      String message = e.getMessage();
      if (e.getCause() != null)
      {
        message = e.getCause().toString();
      }

      IStatus[] childStatus = new Status[1];
      childStatus[0] = StatusUtils.errorStatus( message);
      return StatusUtils.multiStatus(getMessage("MSG_ERROR_AXIS_DEPLOY"), childStatus);

    }
  }

  /**
   * Returns the message string identified by the given key from plugin.properties.
   * 
   * @return The String message.
   */
  public String getMessage(String key)
  {
    return resource.getString(key);
  }

  /**
   * @param javaWSDLParam The javaWSDLParam to set.
   */
  public void setJavaWSDLParam(JavaWSDLParameter javaWSDLParam)
  {
    this.javaWSDLParam = javaWSDLParam;
  }

}
