/*******************************************************************************
 * Copyright (c) 2005 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.consumption.ui.server;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.consumption.ui.command.StartServerCommand;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.TransientResourceContext;
import org.eclipse.wst.command.internal.env.eclipse.EclipseEnvironment;
import org.eclipse.wst.command.internal.env.ui.eclipse.EclipseStatusHandler;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.common.environment.NullStatusHandler;
import org.eclipse.wst.server.core.IServer;

public class StartServerWidget extends SimpleWidgetDataContributor 
{
  private IServer             server_;
  private IStatus              status_;
  private Listener            statusListener_;
  private Button              button_;
  private JobChangeAdapter    jobChangeAdapter_;
  private Text                serverStateText_;
  private ProgressMonitorPart progressMonitor_;
  private String              pluginId_;
  private Composite           buttonGroup_;
    
  /*CONTEXT_ID SSWP0001 Start the server button. */
  private String INFOPOP_SSWP_SERVER_BUTTON = "SSWP0001";
  
  public StartServerWidget( IServer server )
  {
	pluginId_ = "org.eclipse.jst.ws.consumption.ui";
		
    server_ = server;
    
    jobChangeAdapter_ = new JobChangeAdapter()
                        {
                          public void done(final IJobChangeEvent event) 
                          {
                        	Display.getDefault().asyncExec( new Runnable()
                        			                        {
	        					                              public void run() 
							                                  {
	        						                            if( !progressMonitor_.isDisposed() )
	        						                            {
							                                      setServerState();	
							                                      progressMonitor_.done();
							                                      reportErrorIfRequired( (StartServerJob)event.getJob() );
	        						                            }
							                                  }
                        			                        });
                          }
                        };
  }
  
  public WidgetDataEvents addControls(Composite parent, Listener statusListener) 
  {
	statusListener_ = statusListener;
	
	UIUtils      uiUtils     = new UIUtils( pluginId_ );
	Composite    group       = uiUtils.createComposite( parent, 1 );
	
	Text         text1        = uiUtils.createText( group, null, null, null, SWT.READ_ONLY );
	text1.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT1, new String[]{ server_.getName() } ));
	
	Text         text2        = uiUtils.createText( group, null, null, null, SWT.READ_ONLY );
	text2.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT2, new String[]{ server_.getName() } ));
	
	Text         text3        = uiUtils.createText( group, null, null, null, SWT.READ_ONLY );
	text3.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT3, new String[]{ server_.getName() } ));
	
	Text         text4        = uiUtils.createText( group, null, null, null, SWT.READ_ONLY );
	text4.setText( NLS.bind(ConsumptionUIMessages.LABEL_START_SERVER_TEXT4, new String[]{ server_.getName() } )); 
	
	buttonGroup_ = uiUtils.createComposite( group, 2,-1, 0 );
	serverStateText_ = uiUtils.createText( buttonGroup_, null, null, null, SWT.READ_ONLY );
	serverStateText_.setLayoutData( new GridData() );
		
	button_ = uiUtils.createPushButton( buttonGroup_, 
			ConsumptionUIMessages.LABEL_START_SERVER_BUTTON,
			ConsumptionUIMessages.TOOLTIP_START_SERVER_BUTTON,
			                            INFOPOP_SSWP_SERVER_BUTTON );
	
	button_.addSelectionListener( new SelectionAdapter()
			                      {
									 public void widgetSelected( SelectionEvent evt )
		                             {
			                       	   serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTING ) );
			                    	   progressMonitor_.beginTask( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_MSG, ConsumptionUIMessages.TEXT_SERVER_STARTING ), IProgressMonitor.UNKNOWN );
			                    	   button_.setEnabled( false );
			                    	   buttonGroup_.pack();
		                               startServerJob();
		                             }	                          
			                      } );	
	
	progressMonitor_ = new ProgressMonitorPart( group, new GridLayout() );
	progressMonitor_.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
	
	setServerState();
	return this;
  }

  public IStatus getStatus() 
  {
	return status_;
  }
  
  private void setServerState()
  {
	int state = server_.getServerState();
	
	switch( state )
	{
	  case IServer.STATE_STARTED:
	  {
		status_ = Status.OK_STATUS;
		button_.setEnabled( false );
		serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTED ) );
		
	    break;	  
	  }
	  
	  case IServer.STATE_STARTING:
	  {
		status_ = StatusUtils.errorStatus( "" );
		button_.setEnabled( false );  
		serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STARTING ) );
		progressMonitor_.beginTask( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_MSG, ConsumptionUIMessages.TEXT_SERVER_STARTING ), IProgressMonitor.UNKNOWN );
		
		// The server is still starting so we need to reconnect to the job
		// that is starting it.
		startServerJob();
	    break;	  
	  }
	  
	  default:
	  {
		status_ = StatusUtils.errorStatus( "" );
        button_.setEnabled( true );
		serverStateText_.setText( getStateMessage( ConsumptionUIMessages.TEXT_SERVER_STATUS, ConsumptionUIMessages.TEXT_SERVER_STOPPED ) );
		break;  
	  }
	};
	
	statusListener_.handleEvent( null );
	buttonGroup_.pack();
  }  
  
  private String getStateMessage( String mainKey, String subKey )
  {
	return NLS.bind( mainKey, new String[]{ subKey } );
  }
  
  // Connect to an existing server thread otherwise start a new one.
  private void startServerJob()
  {
	IJobManager    jobManager     = Platform.getJobManager();
	Job[]          jobs           = jobManager.find( StartServerFamily );
	StartServerJob startServerJob = null;
	
	// There may be more than one job starting for different servers.
	// Therefore, we need to find the one for our server if it is available.
	for( int index = 0; index < jobs.length; index++ )
	{
	  StartServerJob jobFound = (StartServerJob)jobs[index];
	  
	  if( jobFound.getServer() == server_ )
	  {
	    startServerJob = jobFound;
	    break;
	  }
	}
	
	if( startServerJob != null )
	{
	  synchronized( StartServerFamily ) 
	  {
        IStatus status = startServerJob.getStatus();
        
        // We are using status to determine if the job has completed or not.
        // Normally, we would not get here if the job had already completed,
        // but there is a slim window where the job manager gives us the job
        // and then it immediately completes.
        if( status == null )
        {        
          // The job had not completed yet so we will add a job change listener.
          // We are adding the job listener here so that we don't have to assume
          // that this instance of this widget is the same as the previous instance.
          // If startServerJob already has "jobChangeAdapter_" added to it this
          // method call will not have an effect.(Which is what we want.)
          startServerJob.addJobChangeListener( jobChangeAdapter_ ); 
          
          // Note: this job was reporting progress to different progressMonitor_
          //       control.  We need to tell the job that it should report progress
          //       to our new progressMonitor_ control on this wizard page.
          ProgressMonitorWrapper monitor = (ProgressMonitorWrapper)startServerJob.getMonitor();
          monitor.setMonitor( progressMonitor_ );
        }
        else
        {
          // The job completed before we had a chance to add the job change listener
          // Therefore, we will just call jobChangeAdapter_ directly to notify
          // the UI that the job has completed.
          jobChangeAdapter_.done( null );
        }
	  }
	}
	else
	{
	  startServerJob = new StartServerJob();	
	  startServerJob.addJobChangeListener( jobChangeAdapter_ );
	  startServerJob.schedule();
	}
  }
     
  private void reportErrorIfRequired( StartServerJob serverJob )
  {
	  IStatus status = serverJob.getStatus();
	
	  if( status.getSeverity() == Status.ERROR )
	  {
	    Shell                shell   = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
      EclipseStatusHandler handler = new EclipseStatusHandler( shell );
      
      handler.reportError( status );
	  }
  }
  
  final private static String  StartServerFamily = "StartServerFamily";
  
  // This class is used to start up the server in an Eclipse job.
  private class StartServerJob extends Job
  {
	  private IStatus                status_ = null;
	  private ProgressMonitorWrapper envMonitor_;
	
	  public StartServerJob()
	  {
	    super( "StartServerJob" );
	  
	    envMonitor_ = new ProgressMonitorWrapper( progressMonitor_ );
	  }
	
	  public IServer getServer()
	  {
	    return server_;	
	  }
	
	  public ProgressMonitorWrapper getMonitor()
	  {
	    return envMonitor_;	
	  }
	
	  public boolean belongsTo(Object family) 
	  {
	    return family == StartServerFamily;
	  }

	  protected IStatus run(IProgressMonitor monitor) 
	  {
	    NullStatusHandler        handler         = new NullStatusHandler();
	    TransientResourceContext resourceContext = new TransientResourceContext();
	    EclipseEnvironment       environment     = new EclipseEnvironment( null,resourceContext, handler );
	    StartServerCommand       serverCommand   = new StartServerCommand( false );
	    
	    serverCommand.setServerInstanceId( server_.getId() );
      serverCommand.setEnvironment( environment );
	    
	    try
	    {
	      setStatus( serverCommand.execute( envMonitor_, null ) );		
	    }
	    catch( Throwable exc )
	    {
		    exc.printStackTrace();
	      setStatus( StatusUtils.errorStatus( exc ) );
	    }
	  	
	    return Status.OK_STATUS;
	  }
	
	  // Calls to this method need to first synchronize on the
	  // StartServerFamily object.
	  public IStatus getStatus()
	  {
	    return status_;
	  }
	
	  private void setStatus( IStatus status )
	  {
	    synchronized( StartServerFamily ) 
	    {
        status_ = status;
	    }
	  }
  }
    
  private class ProgressMonitorWrapper implements IProgressMonitor
  {
    private IProgressMonitor monitor_ = new NullProgressMonitor();
  	  	
    public ProgressMonitorWrapper( IProgressMonitor monitor )
    {
      monitor_ = monitor;  
    }
    
    public void setMonitor( IProgressMonitor monitor )
    {
      monitor_ = monitor;	
    }
    
    public void beginTask(final String name, final int totalWork) 
    {
      Display.getDefault().asyncExec( new Runnable()
      		                          {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
                                      	    monitor_.beginTask( name, totalWork );
                                          }
                                        }
      		                          } );
    }

    public void done() 
    {
      Display.getDefault().asyncExec( new Runnable()
                                      {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
              	                            monitor_.done();
                                          }
                                        }
                                      } );
    }

    public void internalWorked(final double work) 
    {
      Display.getDefault().asyncExec( new Runnable()
                                      {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
              	                            monitor_.internalWorked( work );
                                          }
                                        }
                                      } );
    }

    public boolean isCanceled() 
    {
      return progressMonitor_.isDisposed() ? false : monitor_.isCanceled();
    }

    public void setCanceled(boolean value) 
    {
      if( !progressMonitor_.isDisposed() )
      {
  	    monitor_.setCanceled( value );
      }
    }

    public void setTaskName(final String name) 
    {
  	  Display.getDefault().asyncExec( new Runnable()
                                      {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
                  	                        monitor_.setTaskName( name );
                                          }
                                        }
                                      } );
    }

    public void subTask( final String name) 
    {
  	  Display.getDefault().asyncExec( new Runnable()
                                      {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
                  	                        monitor_.subTask( name );
                                          }
                                        }
                                      } );
    }

    public void worked(final int work) 
    {
      Display.getDefault().asyncExec( new Runnable()
                                      {
                                        public void run()
                                        {
                                          if( !progressMonitor_.isDisposed() )
                                          {
              	                            monitor_.worked( work );
                                          }
                                        }
                                      } );
    }
  }
}
