/*******************************************************************************
 * 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.wst.command.internal.env.core.fragment;

import java.util.Stack;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.command.internal.env.core.CommandFactory;
import org.eclipse.wst.command.internal.env.core.CommandManager;
import org.eclipse.wst.command.internal.env.core.EnvironmentCoreMessages;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.data.DataFlowManager;
import org.eclipse.wst.command.internal.env.core.data.DataMappingRegistry;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.environment.ILog;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;



/**
 * The CommandFragmentEngine provides a convienent way to traverse CommandFragments
 * and possiblity execute its associate Command.
 */
public class CommandFragmentEngine implements CommandManager
{
  private Stack            commandStack_;
  private FragmentListener undoFragmentListener_;
  private FragmentListener nextFragmentListener_;
  private FragmentListener afterExecuteFragmentListener_;
  private FragmentListener peekFragmentListener_;
  private DataFlowManager  dataManager_;
  private IEnvironment     environment_;
  private IStatus          lastStatus_;
  
  /**
   * Creates a CommandFragmentEngine.
   * 
   * @param startFragment the root fragment where traversal will begin.
   * @param dataManager the data manager containing all of the data mappings.
   * @param environment the environment.
   */
  public CommandFragmentEngine( CommandFragment startFragment, DataFlowManager dataManager, IEnvironment environment )
  {
  	SequenceFragment root = new SequenceFragment();
  	root.add( startFragment );
  	  	
  	commandStack_ = new Stack();
  	
  	addToStack( root, -1 );
  	addToStack( startFragment, 0 );
  	
  	dataManager_ = dataManager;
  	environment_ = environment;
  } 
  
  /**
   * @return returns the Data mapping registry.
   */
  public DataMappingRegistry getMappingRegistry()
  {
	return dataManager_.getMappingRegistry();
  }
  
  /**
   * 
   * @return the Status from the last Command executed.
   */
  public IStatus getLastStatus()
  {
    return lastStatus_;
  }
  
  /**
   */
  public boolean isUndoEnabled()
  {
    return true;
  }
  
  /**
   * Sets the next fragment listener for this engine.  This listener will be
   * called for each fragment that is traversed in moveForwardToNextStop operation.
   * 
   * @param listener the fragment listener.
   */
  public void setNextFragmentListener( FragmentListener listener )
  {
    nextFragmentListener_ = listener;
  }
  
  public void setAfterExecuteFragmentListener( FragmentListener listener )
  {
    afterExecuteFragmentListener_ = listener;
  }
  
  /**
   * Sets the next fragment listener for this engine.  This listener will be
   * called for each fragment that is traversed in peekForwardToNextStop operation.
   * 
   * @param listener the fragment listener.
   */
  public void setPeekFragmentListener( FragmentListener listener )
  {
    peekFragmentListener_ = listener;
  }
  
  /**
   * Sets the peek fragment listener for this engine.  This listener will be
   * called for each fragment that is traversed in undoToLastStop operation.
   * 
   * @param listener the fragment listener.
   */
  public void setUndoFragmentListener( FragmentListener listener )
  {
    undoFragmentListener_ = listener;
  }
  
  /**
   * Traverse the CommandFragments starting with the CommandFragment on the
   * top of the command fragment stack.  The operation does NOT change the
   * command fragment stack and does not execute any command associated with
   * a CommandFragment.
   */
  public void peekForwardToNextStop()
  {
  	CommandListEntry topEntry      = (CommandListEntry)commandStack_.lastElement();  	
  	int              parentIndex   = topEntry.parentIndex_;
  	CommandFragment  childFragment = topEntry.fragment_; 
  	boolean          continueLoop  = navigateChildFragments( childFragment, false );
  	  	
  	while( parentIndex != -1 && continueLoop )
  	{  	
  	  CommandListEntry parentEntry    = (CommandListEntry)commandStack_.elementAt( parentIndex );
  	  CommandFragment  parentFragment = parentEntry.fragment_;
  	  CommandFragment  nextFragment   = parentFragment.getNextSubFragment( childFragment );
  	  
  	  if( nextFragment == null )
  	  {
  	  	// There are no more sibling fragments to navigate so we will pop up to the parent
  	  	// an continue navigation there.
  	  	parentIndex   = parentEntry.parentIndex_;
  	  	childFragment = parentFragment; 
  	  }
  	  else
  	  {  	  	
  	  	if( navigateChildFragments( nextFragment, true ) ) 
  	  	{
  	  	  // We are continuing to navigate.  This time we want to traverse the sibling
  	  	  // of nextFragment. 
  	  	  childFragment = nextFragment;
  	  	}
  	  	else
  	  	{
  	  	  // We are stopping our navigation.
  	  	  continueLoop = false;
  	  	}
  	  }
  	}
  }
  
  
  /**
   * Traverse the CommandFragments starting with the CommandFragment on the
   * top of the command fragment stack.  This operation does change the
   * command fragment stack and does execute any command associated with
   * a CommandFragment.
   */
  public void moveForwardToNextStop( IProgressMonitor monitor )
  {
  	CommandListEntry topEntry        = (CommandListEntry)commandStack_.lastElement();  	
  	int              parentIndex     = topEntry.parentIndex_;
  	CommandFragment  currentFragment = topEntry.fragment_;  
  	boolean          continueExecute = visitTop( monitor );
  	CommandFragment  childFragment    = currentFragment.getFirstSubFragment();
  	    
  	// If the current fragment has child fragments we need to traverse these children.
  	while( childFragment != null && continueExecute )
  	{
  	  parentIndex = commandStack_.size() - 1;
  	  addToStack( childFragment, parentIndex );
  	  continueExecute = visitTop( monitor );
  	  currentFragment = childFragment;
  	  childFragment   = currentFragment.getFirstSubFragment();
  	}
  	
  	// The previous while loop has guaranteed that currentFragment has no
  	// child fragments. This while loop assumes this to be the case.
  	while( parentIndex != -1 && continueExecute )
  	{  	   	
  	  CommandListEntry parentEntry    = (CommandListEntry)commandStack_.elementAt( parentIndex );
  	  CommandFragment  parentFragment = parentEntry.fragment_;
  	  CommandFragment  nextFragment   = null;
  	  
  	  if( currentFragment == null )
  	  {
  	    nextFragment = parentFragment.getFirstSubFragment();
  	  }
  	  else
  	  {	
  	    nextFragment = parentFragment.getNextSubFragment( currentFragment );
  	  }
  	  
  	  if( nextFragment == null )
  	  {
  	  	// There are no more sibling fragments to navigate so we will pop up to the parent
  	  	// and continue navigation there.
  	  	parentIndex     = parentEntry.parentIndex_;
  	  	currentFragment = parentFragment; 
  	  }
  	  else
  	  {  	
  	  	// We have a new fragment that we need to add to the top of the stack.
  	  	addToStack( nextFragment, parentIndex );  	  	
  	    parentIndex     = commandStack_.size() - 1;  	
  	    continueExecute = visitTop( monitor );
  	    currentFragment = null;  	  	
  	  }
  	}
  }
  
  /**
   * 
   * @return returns true if the there is not longer any elements on the stack.  Note:
   *                 that last two entries are always left on the stack.
   */
  public boolean undoToLastStop()
  {    
  	CommandListEntry topEntry = (CommandListEntry)commandStack_.lastElement();	
  	
	  if( topEntry.fragmentStopped_ && !topEntry.beforeExecute_ )
    {
      // Normally the command at the top of the stack has not been executed.  If
      // it has been execute, it means that we tried to execute and it failed.
      // The first command in the command stack failed.  Therefore, we should
      // only undo this command.
      performUndo( topEntry );
      return topEntry.parentIndex_ == 0;
    }
    
  	performUndo( topEntry );
  		
    while( topEntry.parentIndex_ != 0 )
  	{
      commandStack_.pop();
  	  topEntry = (CommandListEntry)commandStack_.lastElement();	  
      
  	  performUndo( topEntry );
  	  
  	  if( topEntry.fragmentStopped_ )
  	  {
  	    break;
  	  }
  	}
  	
  	return topEntry.parentIndex_ == 0;
  }
   
  private void performUndo( CommandListEntry entry )
  {
    if( entry.parentIndex_ == 0 ) return;
    
	  AbstractDataModelOperation cmd = entry.command_;
  	  
  	if( cmd != null && cmd.canUndo() && !entry.beforeExecute_ )
	{
    try
    {
	    cmd.undo( null, null );
    }
    catch( Exception exc )
    {
      exc.printStackTrace();
    }
    
	  entry.beforeExecute_ = true;
	}
  	  
	undoFragmentListener_.notify( entry.fragment_ );  	
  }
  
  private boolean navigateChildFragments( CommandFragment fragment, boolean visitCurrent )
  {
  	boolean         continueNavigate = true;
  	CommandFragment childFrag        = null; 
  	  
  	if( visitCurrent )
  	{
  	  continueNavigate = peekFragmentListener_.notify( fragment );
      dataManager_.process( fragment );
  	}
  	
  	childFrag = fragment.getFirstSubFragment();
   	
  	while( childFrag != null && continueNavigate )
  	{
  	  continueNavigate = navigateChildFragments( childFrag, true );
  	  childFrag        = fragment.getNextSubFragment( childFrag );
  	}
  	
  	return continueNavigate;
  }
    
  private boolean visitTop( IProgressMonitor monitor )
  {  
  	CommandListEntry entry           = (CommandListEntry)commandStack_.lastElement();
  	boolean         continueNavigate = nextFragmentListener_.notify( entry.fragment_ );
  	  
  	if( continueNavigate )
  	{
  	  // Call the setters for this fragment.
      dataManager_.process( entry.fragment_ );
      
      // Add any rules to the mapping registry before we execute the command.
      entry.fragment_.registerDataMappings( dataManager_.getMappingRegistry() );
   
  	  lastStatus_ = runCommand( entry, monitor );
  	  
      if( afterExecuteFragmentListener_ != null )
      {
        continueNavigate = afterExecuteFragmentListener_.notify( entry.fragment_ );  
        
        if( !continueNavigate )
        {
          // The after execution listener has indicated that execution should stop.
          // Therefore, we will upgrade the severity of the last status to ERROR.
          lastStatus_ = new Status( IStatus.ERROR, 
                                    lastStatus_.getPlugin(), 
                                    lastStatus_.getCode(), 
                                    lastStatus_.getMessage(),
                                    lastStatus_.getException() );
        }
      }
      
  	  if( continueNavigate && lastStatus_.getSeverity() == IStatus.ERROR ) continueNavigate = false;
  	}
  	
   	if( !continueNavigate ) entry.fragmentStopped_ = true;
   	
  	return continueNavigate;
  }
  
  private void addToStack( CommandFragment fragment, int parentIndex )
  {
    CommandListEntry entry = new CommandListEntry( fragment, parentIndex );
    commandStack_.push( entry );
  }
  
  // Subclasses can do initialization before the execution of a command here
  protected void initBeforeExecute( AbstractDataModelOperation operation )
  {  
  }
  
  private IStatus runCommand( CommandListEntry entry, IProgressMonitor monitor )
  {
	CommandFactory factory  = entry.fragment_.getCommandFactory();
  	IStatus      status   = Status.OK_STATUS;
  	
  	if( factory != null )
  	{
  	  AbstractDataModelOperation cmd  = factory.create();
      
  	  entry.command_ = cmd;
  	    
  	  if( cmd != null )
  	  {
  	    dataManager_.process( cmd );
  	  	  
  	    try
  	    {
          initBeforeExecute( cmd );
          
  	      environment_.getLog().log(ILog.INFO, "command", 5001, this, "runCommand", "Executing: " + cmd.getClass().getName());
  	  	    
 	        cmd.setEnvironment( environment_ );
          status = cmd.execute( monitor, null );
          
		      entry.beforeExecute_ = false;
  	    }
  	    catch( Throwable exc )
  	    {
  	      IStatus      unexpectedError = StatusUtils.errorStatus( exc );
          MultiStatus  parentStatus    = new MultiStatus( "id", 0, new IStatus[]{unexpectedError}, 
                                                          EnvironmentCoreMessages.MSG_ERROR_UNEXPECTED_ERROR, null );
  	      environment_.getStatusHandler().reportError( parentStatus );
  	    }
  	    finally
  	    {
  	      String message = "Ok";
  	      
  	      if( status.getSeverity() == Status.ERROR )
  	      {
  	        message = "Error: " + status.getMessage(); 
  	      }
  	      
	      environment_.getLog().log(ILog.INFO, "command", 5001, this, "runCommand", "Execution status: " + message );
  	    }
  	  }
  	}
  	
  	return status;
  }
    
  private class CommandListEntry
  {
  	public CommandListEntry( CommandFragment fragment, int parentIndex )
  	{
  	  fragment_        = fragment;
  	  parentIndex_     = parentIndex;
  	  fragmentStopped_ = false;
	  beforeExecute_   = true;
  	}
  	  	
  	public AbstractDataModelOperation command_;
  	public CommandFragment fragment_;
  	public int             parentIndex_;
  	public boolean         fragmentStopped_;
	public boolean         beforeExecute_;
  }    
}
