/*
 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/*
 * @(#)ManualDeployment.java	1.14 02/01/12
 */
 
package com.sun.cts.implementation.sun;

import java.util.*;
import java.io.*;
import java.net.*;
import javasoft.sqe.javatest.*;
import com.sun.cts.util.*;
import com.sun.cts.porting.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * This is an alternative implementation of the CTSDeploymentInterface.  This
 * implementation prompts the user to deploy the ear manually, and provides
 * an English description of any additional runtime information that may need 
 * to be set.  This code is based on the CTSDeployment class.
 *  
 * @author	Mark Roth
 */	
public class ManualDeployment implements CTSDeploymentInterface
{

    /** Log stream */
    private PrintWriter Log = null;

    /** Dialog title to display when deploying an application */
    private static final String DEPLOY_TITLE = "Deploy Application";

    /** Dialog title to display when undeploying an application */
    private static final String UNDEPLOY_TITLE = "UNDEPLOY Application";

    /** Message to display when deploying an application */
    private static final String DEPLOY_LABEL = 
	"You must deploy this application using the following settings.";

    /** Message to display when undeploying an application */
    private static final String UNDEPLOY_LABEL =
	"You must UNDEPLOY this application at this time.";

	/** Dialog title to display when deploying an application */
    private static final String DEPLOY_CONNECTOR_TITLE = "Deploy Connector";

    /** Dialog title to display when undeploying an application */
    private static final String UNDEPLOY_CONNECTOR_TITLE = "UNDEPLOY Connector";

    /** Message to display when deploying an application */
    private static final String DEPLOY_CONNECTOR_LABEL = 
	"You must deploy this Connector using the following settings.";

    /** Message to display when undeploying an application */
    private static final String UNDEPLOY_CONNECTOR_LABEL =
	"You must UNDEPLOY this Connector at this time.";

    /** Number of rows in dialog */
    private static final int ROWS = 20;

    /** Number of columns in dialog */
    private static final int COLS = 60;

    /** Last result of dialog box */
    private boolean lastResult = false;

    /** The font for the text area */
    private static final Font textAreaFont = new Font( "Monospaced", 
	Font.PLAIN, 12 );
	
    private CTSPropertyManager propMgr = null;

    /**
      * System environment variable for the location of CTS
      */
    private  static final String CTS_HOME   = "CTS_HOME";
	
    /**
     * Sample main class that enables this class to be a utility to output
     * an English description of runtime-specific deployment information about
     * a particular J2EE Application.
     */
    public static void main( String [] args ) {
	if( args.length < 1 ) {
	    System.out.println( 
		"Syntax: java ManualDeployment <ear-file> <runtime-file.xml>*" );
	    System.exit( 1 );
	}

	ManualDeployment deployment = new ManualDeployment();
	deployment.init( new PrintWriter( System.out ));

	String earFile = args[0];
	String[] runtimeFiles = new String[args.length-1];
	for( int i = 0; i < runtimeFiles.length; i++ ) {
	    runtimeFiles[i] = args[i+1];
	}

	DeploymentInfo info = null;
	try {
	    info = new DeploymentInfo( earFile, runtimeFiles );
	}
	catch( IOException e ) {
	    System.err.println( "IOException: " + e.getMessage() );
	    System.exit( 1 );
	}
	catch( DeploymentInfo.ParseException e ) {
	    System.err.println( "ParseException: " + e.getMessage() );
	    System.exit( 1 );
	}

	String runtimeInfo = "No additional info.";

	if( runtimeFiles.length != 0 ) {
	    runtimeInfo = new RuntimeInfo().getRuntimeInfo(info);
	}

	// Construct message
	String message = 
	    "Application: \t" + earFile + "\n" + 
	    "\n" +
	    runtimeInfo;

	System.out.println( message );
    }

    /**
	 * Creates a new CTSDeployment instance.  All output should be printed to 
	 * this PrintWriter. 
	 *
	 * @param	out   The PrintWriter that should be used to log output.
	 * @param	p	  All of the properties as defined in the Javatest .jte file
	 */
	public void init(PrintWriter out)
	{
		Log = out;
                boolean success = true;

                /** Grab $CTS_HOME from the System properties and abort 
                  * if it is not set
                  */
                String ctsHome = System.getProperty(CTS_HOME);

                if(ctsHome != null)
                {
                    Properties props = new Properties();
                    props.put("cts_home", ctsHome);

                   try {
		      propMgr = 
                         CTSPropertyManager.createCTSPropertyManager(props);
                   } catch( Exception e ) {
                      System.err.println( "Exception: " + e.getMessage() );
                      success = false;
                   }
                } else {
                   System.out.println("Error: You must specify the property -D"
                      +"$CTS_HOME=path option!");
                   success = false;
                }

                if(!success) {
                   System.exit(1);
                }
	}

    /**
     * Returns a list of runtime files to be processed for runtime-specific
     * information.
     */
    private String[] getRuntimeFiles(String s) throws CTSDeploymentException {
	String[] sRunTimeFiles = null;
	StringTokenizer st = new StringTokenizer(s);
	int iCount = st.countTokens();

	sRunTimeFiles = new String[iCount];
	    
	for(int ii = 0; ii < iCount; ii++) {
	    //set runtime info for each file
	    sRunTimeFiles[ii] = st.nextToken().trim();
	}	

	return sRunTimeFiles;
    }

    /**
     * This method is called by CTSScript to deploy an .ear file into the
     * server.
     * <p>
     * The following properties are available from the DeploymentInfo class
     * for this method's use:
     * <p>
     * generateSQL - If true, SQL should be generated.
     * 
     * @param info The deployment information
     * @exception CTSDeploymentException Thrown if the application could not
     *     be deployed.
     */
    public String deploy(DeploymentInfo info) throws CTSDeploymentException {
	String bGenerateSQL = info.getProperty("generateSQL");
	String sDeployHost = info.getProperty("deployment_host");
	String sApp = info.getEarFile();
	String[] sRunTimeFileArray = info.getRuntimeFiles();

	String runtimeInfo = "No additional info.";

	if( sRunTimeFileArray != null ) {
	    runtimeInfo = new RuntimeInfo().getRuntimeInfo(info);
	}
	else {
	    // no runtime deployment information
	}

	deployMessage( sApp, sDeployHost, runtimeInfo );

	return "";
    }

    /**
     * This method is called by CTSScript to undeploy an .ear from the server.
     * <p>
     * The following properties is available for this method's use:  
     * <p>
     * ear_file - the fully qualified application (.ear file) 
     *
     * @param	p	The properties as defined in the Javatest .jte file
     *
     * @exception CTSDeploymentException Thrown if the application could not
     *     be deployed.
     */
    public void undeploy(Properties p) throws CTSDeploymentException {
	String sDeployHost = p.getProperty("deployment_host");
	String sApp = p.getProperty("ear_file");
	String sAppName = (new File(sApp)).getName();
	String sCTSDeploymentDir = sApp.substring(0,
	    sApp.lastIndexOf(File.separator)+1) + "cts_dep";	

	File ctsDeployDir = new File(sCTSDeploymentDir);
		
	sAppName = sAppName.substring(0, sAppName.lastIndexOf("."));

	undeployMessage( sApp, sDeployHost );
    }		

    /**
     * This method is called by CTSSuiteSynchronizer to check whether or not
     * an application ear is deployed.  This information is used to determine
     * whether or not the harness needs to undeploy it.	 The following 
     * properties is available for this method's use:  
     * 
     * ear_file - the fully qualified application (.ear file) 
     *
     * This default implementation asks the user if the application is
     * deployed or not.
     *
     * @param	p	The properties as defined in the Javatest .jte file
     * @return  	True if the app is deployed.  False if not.
     */
    public boolean isDeployed(Properties p) throws CTSDeploymentException {
        String sDeployHost = p.getProperty("deployment_host");
	String sApp = p.getProperty("ear_file");
	int result = JOptionPane.showConfirmDialog( null, 
	    "Is the application " + sApp + " deployed on " + sDeployHost + "?",
	    "Deployment Question",JOptionPane.YES_NO_OPTION );
	return (result == JOptionPane.YES_OPTION);
    }
	
	/**
	 * This method is called to deploy a connector (.rar file).  We extract 
	 * such info as deployment_host 
	 * and rar_file from these props.  The following properties are available 
	 * for this method's use:  
	 * 
	 * rar_file - the fully qualified connector file (.rar file) 
	 * deployment_host - the host name of the machine to deploy it to 
	 *
	 * @param	p	Properties specific to the currently running test
	 */
	public void deployConnector(Properties p) throws CTSDeploymentException
	{
		String sDeployHost = p.getProperty("deployment_host");
		String sRarFileName = p.getProperty("rar_file");

		deployMessage( sRarFileName, sDeployHost, "" );
	}
	
	/**
	 * This method is called to undeploy a connector (.rar file).  
	 * We extract such info as deployment_host 
	 * and rar_file from these props.  The following properties are available 
	 * for this method's use:  
	 * 
	 * rar_file - the fully qualified connector file (.rar file) 
	 * deployment_host - the host name of the machine to deploy it to 
	 *
	 * @param	p	Properties specific to the currently running test
	 */
	public void undeployConnector(Properties p) throws CTSDeploymentException
	{
		String sDeployHost = p.getProperty("deployment_host");
		String sRarFileName = p.getProperty("rar_file");
		
		undeployMessage( sRarFileName, sDeployHost );
	}
	
	/**
	 * This method is called to check to see if a given connector (.rar file) 
	 * is deployed.  We extract such info
	 * as deployment_host and rar_file from these props.  The following 
	 * properties are available for this method's use:  
	 * 
	 * rar_file - the fully qualified connector file (.rar file) 
	 * deployment_host - the host name of the machine to deploy it to 
	 *
	 * @param	p	Properties specific to the currently running test
	 */
	public boolean isConnectorDeployed(Properties p) throws CTSDeploymentException
	{
		String sDeployHost = p.getProperty("deployment_host");
		String sRarFileName = p.getProperty("rar_file");
                    
		int result = JOptionPane.showConfirmDialog( null, 
	    "Is the connector, " + sRarFileName + ", deployed on " + 
		sDeployHost + "?", "Deployment Question",JOptionPane.YES_NO_OPTION );
		return (result == JOptionPane.YES_OPTION);
	}
	
	/**
     * Returns the arguments that must be passed to the application client.
     * Assumes the arguments are the same as those for the Reference 
     * Implementation.
     *
     * @param p A properties object containing the properties "ear_file"
     *     and "client_name"
     * @return The arguments to pass to the application client.
     */
    public String getAppClientArgs(Properties p)
    {
	String executeArgs = p.getProperty("executeArgs");
	 
	if(executeArgs == null)
	    executeArgs = "-client " + p.getProperty("ear_file") + 
		" -name " + p.getProperty("client_name");
	else
	    executeArgs += " -client " + p.getProperty("ear_file") + 
		" -name " + p.getProperty("client_name");

	return executeArgs;
    }

    /**
     * Displays a message to the user to deploy the given application and
     * click the success button.  Does not return until the user clicks success.
     * If the user clicks failure, a CTSDeploymentException is thrown.
     *
     * @param earFile The name of the ear to deploy
     * @param serverHost The name of the server to deploy it to.
     * @param runtimeInfo Any additional runtime information to report to user.
     */
    private void deployMessage( String earFile, String serverHost, 
	String runtimeInfo ) throws CTSDeploymentException 
    {
	String message = "";

	// Construct message
	message += 
	    "Application: \t" + earFile + "\n" + 
	    "Server: \t" + serverHost + "\n" +
	    "\n" +
	    runtimeInfo;

	showMessage( DEPLOY_TITLE, DEPLOY_LABEL, message, 
	    "Deployed Successfully", "Deployment Failed" );

	if( lastResult == false ) {
	    throw new CTSDeploymentException( "User cancelled deployment." );
	}
    }

    /**
     * Displays a message to the user to undeploy the given application and
     * click the OK button.  Does not return until the user clicks OK.
     * If the user clicks Cancel, a CTSDeploymentException is thrown.
     *
     * @param earFile The name of the ear to undeploy
     * @param serverHost The name of the server to undeploy it from.
     */
    private void undeployMessage( String earFile, String serverHost ) 
	throws CTSDeploymentException 
    {
	String message = "";

	// Construct message
	message += 
	    "Application: \t" + earFile + "\n" + 
	    "Server: \t" + serverHost + "\n";

	showMessage( UNDEPLOY_TITLE, UNDEPLOY_LABEL, message,
	    "Undeployed Successfully", "Undeployment Failed" );

	if( lastResult == false ) {
	    throw new CTSDeploymentException( "User cancelled undeployment." );
	}
    }

    /**
     * Displays a message to the user and waits for OK or Cancel to be
     * clicked.  When done, the lastResult attribute will be set to true if
     * the user clicked OK or false if the user clicked Cancel.  The method
     * will not return until the dialog is closed.
     *
     * @param title The title of the dialog
     * @param label The label to display at the top of the dialog
     * @param message The message text to display (can be copied and pasted)
     * @param okButtonText The text to display on the success button
     * @param cancelButtonText The text to display on the failed button
     *
     */
    private void showMessage( String title, String label, String message,
	String okButtonText, String cancelButtonText ) 
    {
	// Construct dialog box:
	final Dialog dialog = new Dialog( new Frame(), title );
	dialog.setModal( true );
	Label lbl = new Label( label );
        dialog.add( BorderLayout.NORTH, lbl );

	TextArea textArea = new TextArea( ROWS, COLS );
	textArea.setFont( textAreaFont );
	textArea.setText( message );
	dialog.add( BorderLayout.CENTER, textArea );

	Panel buttonPanel = new Panel();
	buttonPanel.setLayout( new FlowLayout() );
	Button okButton = new Button( okButtonText );
	buttonPanel.add( okButton );
	Button cancelButton = new Button( cancelButtonText );
	buttonPanel.add( cancelButton );
	dialog.add( BorderLayout.SOUTH, buttonPanel );

	okButton.addActionListener(
	    new ActionListener() {
		public void actionPerformed( ActionEvent e ) {
		    lastResult = true;
		    dialog.dispose();
		}
	    } );

	cancelButton.addActionListener(
	    new ActionListener() {
		public void actionPerformed( ActionEvent e ) {
		    lastResult = false;
		    dialog.dispose();
		}
	    } );

	// Wait for user to make selection.
	dialog.pack();
	dialog.show();
    }
	
	public Hashtable getInteropJNDINames(DeploymentInfo[] infoArray)
	{
		return new Hashtable();
	}

}





