/*******************************************************************************
 * 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
 * yyyymmdd   bug     Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060329   127016 andyzhai@ca.ibm.com - Andy Zhai
 * 20060404   134791 andyzhai@ca.ibm.com - Andy Zhai
 *******************************************************************************/
package org.eclipse.jst.ws.internal.axis.consumption.core.command;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.axis.constants.Scope;
import org.apache.axis.wsdl.toJava.Emitter;
import org.apache.axis.wsdl.toJava.GeneratedFileInfo;
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.AxisConsumptionCoreMessages;
import org.eclipse.jst.ws.internal.axis.consumption.core.common.JavaWSDLParameter;
import org.eclipse.jst.ws.internal.axis.consumption.core.context.AxisEmitterContext;
import org.eclipse.jst.ws.internal.axis.consumption.core.context.AxisEmitterDefaults;
import org.eclipse.jst.ws.internal.axis.consumption.core.plugin.WebServiceAxisConsumptionCorePlugin;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.plugin.WebServicePlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.common.FileResourceUtils;
import org.eclipse.wst.command.internal.env.core.common.ProgressUtils;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.environment.ILog;
import org.eclipse.wst.common.environment.IStatusHandler;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;


public class WSDL2JavaCommand extends AbstractDataModelOperation {

	private final String DEPLOY_TYPE = "deploy"; //$NON-NLS-1$
	private final String UNDEPLOY_TYPE = "undeploy"; //$NON-NLS-1$
	private final String TEMP = "temp"; //$NON-NLS-1$
	private JavaWSDLParameter javaWSDLParam;
	private String wsdlURI;
	private String httpBasicAuthUsername;
	private String httpBasicAuthPassword;
	private List deployFiles;
	private List javaFiles;
	private File tempOutputFile;

	public WSDL2JavaCommand() {
	}

	public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable )
	{
		IEnvironment environment = getEnvironment();
		IStatus status;
		if (javaWSDLParam == null) {
			status = StatusUtils.errorStatus(
					AxisConsumptionCoreMessages.MSG_ERROR_JAVA_WSDL_PARAM_NOT_SET);
			environment.getStatusHandler().reportError(status);
			return status;
		}
		
		if (wsdlURI != null) //bottom up case has already has the correct WSDL on javaWSDLParam
		{
			javaWSDLParam.setInputWsdlLocation(wsdlURI);
		}
		javaWSDLParam.setHTTPUsername(httpBasicAuthUsername);
		javaWSDLParam.setHTTPPassword(httpBasicAuthPassword);
		
		Emitter wsdl2Java = new Emitter();
		if (environment.getLog().isEnabled("emitter")) {
			wsdl2Java.setVerbose(true);
		} else {
			wsdl2Java.setVerbose(false);
		}
		boolean serverSide = javaWSDLParam.getServerSide() == JavaWSDLParameter.SERVER_SIDE_BEAN;
		wsdl2Java.setServerSide(serverSide);
		if (serverSide) {
			wsdl2Java.setSkeletonWanted(javaWSDLParam.isSkeletonDeploy());
		}
		
		// create temporary directory to use as output directory for wsdl2java
		tempOutputFile = createTempDir();
		wsdl2Java.setOutputDir(tempOutputFile.toString());
		
		try {
			if (javaWSDLParam.isMetaInfOnly()) {
				// for the case Java2WSDL-WSDL2Java
				HashMap pck2nsMap = javaWSDLParam.getMappings();
				if (pck2nsMap != null) {
					HashMap ns2pckMap = new HashMap();
					Iterator keys = pck2nsMap.keySet().iterator();
					while (keys.hasNext()) {
						String pakage = (String) keys.next();
						String namespace = (String) pck2nsMap.get(pakage);
						ns2pckMap.put(namespace, pakage);
					}
					wsdl2Java.setNamespaceMap(ns2pckMap);
				}
			} else {
				//  for the case WSDL2Java			
				if (javaWSDLParam.getMappings() != null) {
					wsdl2Java.setNamespaceMap(javaWSDLParam.getMappings());
				}
			}
			environment.getLog().log(ILog.INFO, 5019, this, "execute", "Java output = " + javaWSDLParam.getJavaOutput());
			if (javaWSDLParam.getHTTPPassword() != null) {
				wsdl2Java.setPassword(javaWSDLParam.getHTTPPassword());
				environment.getLog().log(ILog.INFO, 5081, this, "execute", "password: " + javaWSDLParam.getHTTPPassword());
			}
			if (javaWSDLParam.getHTTPUsername() != null) {
				wsdl2Java.setUsername(javaWSDLParam.getHTTPUsername());
				environment.getLog().log(ILog.INFO, 5082, this, "execute", "username: " + javaWSDLParam.getHTTPUsername());
			}
			environment.getLog().log(ILog.INFO, 5020, this, "execute", "WSDL Location = " + javaWSDLParam.getInputWsdlLocation());
			
			// If timeout is not set, the default timeout for wsdl2java is 45 seconds.  
			// The user can change the timeout value by setting 
			// "-DAxisWsdl2JavaTimeout=<timeout_value_in_milliseconds>" as VM argument
			// when starting the Eclipse workbench.
			//
			// For example, enter the following command to start the Eclipse workbench 
			// in order to set the Axis WSDL to Java emitter timeout to 60 seconds:
			//
			// 		eclipse -vmargs "-DAxisWsdl2JavaTimeout=60000"
			//
			// When AxisWsdl2JavaTimeout is set, the Axis emitter preference page timeout setting is ignored
		    AxisEmitterContext context = WebServiceAxisConsumptionCorePlugin.getInstance().getAxisEmitterContext();
			String wsdl2JavaTimeoutProperty = System.getProperty("AxisWsdl2JavaTimeout");
			long timeout;
			if (wsdl2JavaTimeoutProperty != null) {
				timeout = new Integer(wsdl2JavaTimeoutProperty).longValue();
				wsdl2Java.setTimeout(timeout);
				environment.getLog().log(ILog.INFO, 5091, this, "execute", "AxisWsdl2JavaTimeout = " + timeout);				
			}
			else if(context.getTimeOut() != AxisEmitterDefaults.getTimeOutDefault())
			{
				timeout = context.getTimeOut() == -1 ? -1 : context.getTimeOut()* 1000; 
				wsdl2Java.setTimeout(timeout);
				environment.getLog().log(ILog.INFO, 5100, this, "execute", "Timeout = " + timeout);
			}
		    if (context.getDeployScopeType() != AxisEmitterDefaults.getDeployScopeDefault())
		    {
		    	switch (context.getDeployScopeType())
		    	{
		    		case AxisEmitterContext.DEPLOY_SCOPE_TYPE_APPLICATION:
		    			wsdl2Java.setScope(Scope.APPLICATION);
						environment.getLog().log(ILog.INFO, 5101, this, "execute", " Deploy Scope: Application" );
		    			break;
		    		case AxisEmitterContext.DEPLOY_SCOPE_TYPE_REQUEST:
		    			wsdl2Java.setScope(Scope.REQUEST);
						environment.getLog().log(ILog.INFO, 5102, this, "execute", " Deploy Scope: Request" );
		    			break;
		    		case AxisEmitterContext.DEPLOY_SCOPE_TYPE_SESSTION:
		    			wsdl2Java.setScope(Scope.SESSION);
						environment.getLog().log(ILog.INFO, 5103, this, "execute", " Deploy Scope: Session" );
		    			break;
		    		default:
		    	}
		    }
		    
		    if (context.isAllWantedEnabled() != AxisEmitterDefaults.getAllWantedDefault())
		    {
		    	wsdl2Java.setAllWanted(context.isAllWantedEnabled());
				environment.getLog().log(ILog.INFO, 5104, this, "execute", " set AllWanted : " + context.isAllWantedEnabled() );
		    }

		    if (context.isHelperWantedEnabled() != AxisEmitterDefaults.getHelperWantedDefault())
		    {
		    	wsdl2Java.setHelperWanted(context.isHelperWantedEnabled());
				environment.getLog().log(ILog.INFO, 5105, this, "execute", " set HelperWanted : " + context.isHelperWantedEnabled() );
			}
		    if (context.isWrapArraysEnabled() != AxisEmitterDefaults.getWrapArraysDefault())
		    {
		    	wsdl2Java.setWrapArrays(context.isWrapArraysEnabled());
				environment.getLog().log(ILog.INFO, 5106, this, "execute", " set WrapArrays : " + context.isWrapArraysEnabled() );
		    }
			
			ProgressUtils.report(monitor, NLS.bind(AxisConsumptionCoreMessages.MSG_PARSING_WSDL, javaWSDLParam.getInputWsdlLocation() ) );
			
			wsdl2Java.run(javaWSDLParam.getInputWsdlLocation());
			
			javaFiles = wsdl2Java.getGeneratedFileNames();
			
			deployFiles = new ArrayList();
			if (serverSide) {
				// set deployment files
				List deploymentFiles1 = wsdl2Java.getGeneratedFileInfo().findType(DEPLOY_TYPE);
				List deploymentFiles2 = wsdl2Java.getGeneratedFileInfo().findType(UNDEPLOY_TYPE);
				if (deploymentFiles1 != null && deploymentFiles2 != null) {
					deploymentFiles1.addAll(deploymentFiles2);
					for (int i = 0; i < deploymentFiles1.size(); i++) {
						GeneratedFileInfo.Entry entry = (GeneratedFileInfo.Entry) deploymentFiles1.get(i);
						deployFiles.add(entry.fileName);
					}
				}	
				javaFiles.removeAll(deployFiles);
			}
			
			status = moveGeneratedFiles(environment, monitor);
			
		} catch (Exception e) {
			environment.getLog().log(ILog.ERROR, 5021, this, "execute", e);
			status = StatusUtils.errorStatus(
					AxisConsumptionCoreMessages.MSG_ERROR_WSDL_JAVA_GENERATE + " " //$NON-NLS-1$
					+ e.toString(), e);
			environment.getStatusHandler().reportError(status);
		} finally {
			deleteDir(tempOutputFile); 			
		}
		return status;	
	}
	  
	public IStatus moveGeneratedFiles( IEnvironment environment, IProgressMonitor monitor ) 
	{
		IStatus status = Status.OK_STATUS;
		
		FileInputStream finStream = null;
		
		try {
			String outputDir, javaOutput;
			outputDir = removeFileProtocol(javaWSDLParam.getOutput());
			javaOutput = removeFileProtocol(javaWSDLParam.getJavaOutput());
			ResourceContext context = WebServicePlugin.getInstance().getResourceContext();				
			
			IPath outputPath = new Path (outputDir);
			
			String fileName;
			IPath targetPath=null;
			IStatusHandler statusHandler = environment.getStatusHandler();
			String deployFile;
			Iterator iterator;
			
			String tempOutputDir = tempOutputFile.toString();
			String [] movedDeployFiles = new String [deployFiles.size()];
			iterator = deployFiles.iterator();
			int i = 0;
			while (iterator.hasNext()) {
				deployFile = (String) iterator.next();
				File source = new File(deployFile);
				finStream = new FileInputStream(source);
				if (finStream != null) {
					if (deployFile.startsWith(tempOutputDir)) {
						fileName = deployFile.substring(tempOutputDir.length());
						targetPath = outputPath.append(fileName).makeAbsolute();  
						FileResourceUtils.createFileAtLocation(context,  
								targetPath,
								finStream,
								monitor,
								statusHandler);
						movedDeployFiles[i++]= ResourceUtils.getWorkspaceRoot().getFileForLocation(targetPath).getLocation().toString();
					}
					finStream.close();
				}
			}
			
			javaWSDLParam.setDeploymentFiles(movedDeployFiles);
			
			IPath javaOutputPath = new Path (javaOutput);
			
			String javaFile;
			String fullClassName = null;
			String [] movedJavaFiles =  new String [javaFiles.size()];
			iterator = javaFiles.iterator();
			i = 0;
			while (iterator.hasNext()) {
				javaFile = (String) iterator.next();
				File source = new File(javaFile);
				finStream = new FileInputStream(source);
				if (finStream != null) {
					// for the case Java2WSDL-WSDL2Java, no need to move Java files, just delete them
					if (!javaWSDLParam.isMetaInfOnly()) {
						// for the case WSDL2Java, move Java files to Java output directory
						if (javaFile.startsWith(tempOutputDir)) {
							fullClassName = javaFile.substring(tempOutputDir.length());
							targetPath = javaOutputPath.append(fullClassName).makeAbsolute(); 
							FileResourceUtils.createFileAtLocation(context,  
									targetPath,
									finStream,
									monitor,
									statusHandler);
							movedJavaFiles[i++]= ResourceUtils.getWorkspaceRoot().getFileForLocation(targetPath).getLocation().toString();
						}
					}
					
					finStream.close();
				}
			}
			javaWSDLParam.setJavaFiles(movedJavaFiles);
			
		} catch (Exception e) {
			status = StatusUtils.errorStatus(NLS.bind(AxisConsumptionCoreMessages.MSG_ERROR_MOVE_RESOURCE,new String[]{e.getLocalizedMessage()}), e);
			environment.getStatusHandler().reportError(status);
			
		} finally {
			if (finStream != null) {
				try {
					finStream.close();
				} catch (IOException e) {
				}
			}			
		}
		
		return status;
	}

	/**
	 * Deletes all files and subdirectories under dir. 
	 * Just ignore and keep going if delete is not successful
	 * 
	 * @param dir directory to delete
	 */
	public void deleteDir(File dir) {
		if (dir.isDirectory()) {
			String[] children = dir.list();
			for (int i = 0; i < children.length; i++) {
				deleteDir(new File(dir, children[i]));
			}
		}
		// The directory is now empty so delete it
		dir.delete();
	}
	
	/**
	 * Creates a temporary directory under the plugin's state location (i.e.
	 * .metadata/.plugin directory)
	 * 
	 * @return File
	 */
	private File createTempDir() {
		String pluginTempDir = WebServiceAxisConsumptionCorePlugin
		.getInstance().getStateLocation().toString();
		File tempDir = new File(pluginTempDir);
		File newTempDir = null;
		try {
			newTempDir = File.createTempFile(TEMP, "", tempDir);
			// delete the temp file and create a temp directory instead
			if (newTempDir.delete()) {
				if (newTempDir.mkdir()) {
					tempDir = newTempDir;
				}
			}
			return tempDir;
		} catch (Exception e) {
			return tempDir;
		}
	}
		
	/*
	 * Hack: Axis doesn't like file URLs
	 */
	private String removeFileProtocol(String s) {
		if (s.startsWith("file:")) {
			String newS = s.substring(5, s.length());
			int i = newS.indexOf(':');
			if (i != -1) {
				String protocol = newS.substring(0, i);
				int j = protocol.indexOf('/');
				int k = protocol.indexOf('\\');
				int max = Math.max(j, k);
				if (max != -1)
					newS = newS.substring(max + 1, newS.length());
			}
			return newS;
		}
		return s;
	}

	public Status undo(IEnvironment environment) {
		return null;
	}

	public Status redo(IEnvironment environment) {
		return null;
	}

	public void setJavaWSDLParam(JavaWSDLParameter javaWSDLParam) {
		this.javaWSDLParam = javaWSDLParam;
	}

	public JavaWSDLParameter getJavaWSDLParam() {
		return javaWSDLParam;
	}

	/**
	 * @param httpBasicAuthPassword
	 *            The httpBasicAuthPassword to set.
	 */
	public void setHttpBasicAuthPassword(String httpBasicAuthPassword) {
		this.httpBasicAuthPassword = httpBasicAuthPassword;
	}

	/**
	 * @param httpBasicAuthUsername
	 *            The httpBasicAuthUsername to set.
	 */
	public void setHttpBasicAuthUsername(String httpBasicAuthUsername) {
		this.httpBasicAuthUsername = httpBasicAuthUsername;
	}

	public void setWsdlURI(String wsdlURI) {
		this.wsdlURI = wsdlURI;
	}

}
