<?php
/**
 * File containing the ezcWorkflowExecution class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Workflow
 * @version //autogen//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Abstract base class for workflow execution engines.
 *
 * ezcWorkflowExecution provides all functionality necessary to execute
 * a workflow. However, it does not provide functionality to make the
 * execution of a workflow persistent and hence usuable over more than
 * one PHP run.
 *
 * Implementations must implement the do* methods and provide the means
 * to store the execution data to a persistent medium.
 *
 * @property ezcWorkflowDefinitonStorage $definitionStorage
 *           The definition handler used to fetch subworkflows if needed.
 * @property ezcWorkflow                 $workflow
 *           The workflow being executed.
 *
 * @package Workflow
 * @version //autogen//
 * @mainclass
 */
abstract class ezcWorkflowExecution
{
    /**
     * Container to hold the properties
     *
     * @var array(string=>mixed)
     */
    protected $properties = array(
      'definitionStorage' => null,
      'workflow' => null
    );

    /**
     * Execution ID.
     *
     * @var integer
     */
    protected $id;

    /**
     * Nodes of the workflow being executed that are activated.
     *
     * @var ezcWorkflowNode[]
     */
    protected $activatedNodes = array();

    /**
     * Number of activated nodes.
     *
     * @var integer
     */
    protected $numActivatedNodes = 0;

    /**
     * Number of activated end nodes.
     *
     * @var integer
     */
    protected $numActivatedEndNodes = 0;

    /**
     * Nodes of the workflow that started a new thread of execution.
     *
     * @var array
     */
    protected $threads = array();

    /**
     * Sequence for thread ids.
     *
     * @var integer
     */
    protected $nextThreadId = 0;

    /**
     * Flag that indicates whether or not this execution has been cancelled.
     *
     * @var bool
     */
    protected $cancelled;

    /**
     * Flag that indicates whether or not this execution has ended.
     *
     * @var bool
     */
    protected $ended;

    /**
     * Flag that indicates whether or not this execution has been resumed.
     *
     * @var bool
     */
    protected $resumed;

    /**
     * Flag that indicates whether or not this execution has been suspended.
     *
     * @var bool
     */
    protected $suspended;

    /**
     * Plugins registered for this execution.
     *
     * @var array
     */
    protected $plugins = array();

    /**
     * Workflow variables.
     *
     * @var array
     */
    protected $variables = array();

    /**
     * Workflow variables the execution is waiting for.
     *
     * @var array
     */
    protected $waitingFor = array();

    /**
     * Property read access.
     *
     * @throws ezcBasePropertyNotFoundException
     *         If the the desired property is not found.
     *
     * @param string $propertyName Name of the property.
     * @return mixed Value of the property or null.
     * @ignore
     */
    public function __get( $propertyName )
    {
        switch ( $propertyName )
        {
            case 'definitionStorage':
            case 'workflow':
                return $this->properties[$propertyName];
        }

        throw new ezcBasePropertyNotFoundException( $propertyName );
    }

    /**
     * Property write access.
     *
     * @param string $propertyName Name of the property.
     * @param mixed $val  The value for the property.
     *
     * @throws ezcBaseValueException
     *         If a the value for the property definitionStorage is not an
     *         instance of ezcWorkflowDefinitionStorage.
     * @throws ezcBaseValueException
     *         If a the value for the property workflow is not an instance of
     *         ezcWorkflow.
     * @ignore
     */
    public function __set( $propertyName, $val )
    {
        switch ( $propertyName )
        {
            case 'definitionStorage':
                if ( !( $val instanceof ezcWorkflowDefinitionStorage ) )
                {
                    throw new ezcBaseValueException( $propertyName, $val, 'ezcWorkflowDefinitionStorage' );
                }

                $this->properties['definitionStorage'] = $val;

                return;

            case 'workflow':
                if ( !( $val instanceof ezcWorkflow ) )
                {
                    throw new ezcBaseValueException( $propertyName, $val, 'ezcWorkflow' );
                }

                $this->properties['workflow'] = $val;

                return;
        }

        throw new ezcBasePropertyNotFoundException( $propertyName );
    }

    /**
     * Property isset access.
     *
     * @param string $propertyName Name of the property.
     * @return bool True is the property is set, otherwise false.
     * @ignore
     */
    public function __isset( $propertyName )
    {
        switch ( $propertyName )
        {
            case 'definitionStorage':
            case 'workflow':
                return true;
        }

        return false;
    }

    /**
     * Starts the execution of the workflow and returns the execution id.
     *
     * $parentId is used to specify the execution id of the parent workflow
     * when executing subworkflows. It should not be used when manually
     * starting workflows.
     *
     * Calls doStart() right before the first node is activated.
     *
     * @param int $parentId
     * @return mixed Execution ID if the workflow has been suspended,
     *               null otherwise.
     * @throws ezcWorkflowExecutionException
     *         If no workflow has been set up for execution.
     */
    public function start( $parentId = null )
    {
        if ( $this->workflow === null )
        {
            throw new ezcWorkflowExecutionException(
              'No workflow has been set up for execution.'
            );
        }

        $this->cancelled = false;
        $this->ended     = false;
        $this->resumed   = false;
        $this->suspended = false;

        $this->doStart( $parentId );
        $this->loadFromVariableHandlers();

        foreach ( $this->plugins as $plugin )
        {
            $plugin->afterExecutionStarted( $this );
        }

        // Start workflow execution by activating the start node.
        $this->workflow->startNode->activate( $this );

        // Continue workflow execution until there are no more
        // activated nodes.
        $this->execute();

        // Return execution ID if the workflow has been suspended.
        if ( $this->isSuspended() )
        {
            return (int)$this->id;
        }
    }

    /**
     * Suspends workflow execution.
     *
     * This method is usually called by the execution environment when there are no more
     * more activated nodes that can be executed. This is commonly the case with input
     * nodes waiting for input.
     *
     * This method calls doSuspend() before calling saveToVariableHandlers() allowing
     * reimplementations to save variable and node information.
     *
     * @ignore
     */
    public function suspend()
    {
        $this->cancelled = false;
        $this->ended     = false;
        $this->resumed   = false;
        $this->suspended = true;

        $this->saveToVariableHandlers();

        $keys     = array_keys( $this->variables );
        $count    = count( $keys );
        $handlers = $this->workflow->getVariableHandlers();

        for ( $i = 0; $i < $count; $i++ )
        {
            if ( isset( $handlers[$keys[$i]] ) )
            {
                unset( $this->variables[$keys[$i]] );
            }
        }

        $this->doSuspend();

        foreach ( $this->plugins as $plugin )
        {
            $plugin->afterExecutionSuspended( $this );
        }
    }

    /**
     * Resumes workflow execution of a suspended workflow.
     *
     * $executionId is the id of the execution to resume. $inputData is an
     * associative array of the format array( 'variable name' => value ) that should
     * contain new workflow variable data required to resume execution.
     *
     * Calls do doResume() before the variables are loaded using the variable handlers.
     *
     * @param array   $inputData    The new input data.
     * @throws ezcWorkflowInvalidInputException if the input given does not match the expected data.
     * @throws ezcWorkflowExecutionException if there is no prior ID for this execution.
     */
    public function resume( array $inputData = array() )
    {
        if ( $this->id === null )
        {
            throw new ezcWorkflowExecutionException(
              'No execution id given.'
            );
        }

        $this->cancelled = false;
        $this->ended     = false;
        $this->resumed   = true;
        $this->suspended = false;

        $this->doResume();
        $this->loadFromVariableHandlers();

        $errors = array();

        foreach ( $inputData as $variableName => $value )
        {
            if ( isset( $this->waitingFor[$variableName] ) )
            {
                if ( $this->waitingFor[$variableName]['condition']->evaluate( $value ) )
                {
                    $this->setVariable( $variableName, $value );
                    unset( $this->waitingFor[$variableName] );
                }
                else
                {
                    $errors[$variableName] = (string)$this->waitingFor[$variableName]['condition'];
                }
            }
        }

        if ( !empty( $errors ) )
        {
            throw new ezcWorkflowInvalidInputException( $errors );
        }

        foreach ( $this->plugins as $plugin )
        {
            $plugin->afterExecutionResumed( $this );
        }

        $this->execute();

        // Return execution ID if the workflow has been suspended.
        if ( $this->isSuspended() )
        {
            // @codeCoverageIgnoreStart
            return $this->id;
            // @codeCoverageIgnoreEnd
        }
    }

    /**
     * Cancels workflow execution with the node $endNode.
     *
     * @param ezcWorkflowNode $node
     */
    public function cancel( ezcWorkflowNode $node = null )
    {
        if ( $node !== null )
        {
            foreach ( $this->plugins as $plugin )
            {
                $plugin->afterNodeExecuted( $this, $node );
            }
        }

        $this->activatedNodes    = array();
        $this->numActivatedNodes = 0;
        $this->waitingFor        = array();

        if ( count( $this->workflow->finallyNode->getOutNodes() ) > 0 )
        {
            $this->workflow->finallyNode->activate( $this );
            $this->execute();
        }

        $this->cancelled = true;
        $this->ended     = false;

        $this->end( $node );
        $this->doEnd();
    }

    /**
     * Ends workflow execution with the node $endNode.
     *
     * End nodes must call this method to end the execution.
     *
     * @param ezcWorkflowNode $node
     * @ignore
     */
    public function end( ezcWorkflowNode $node = null )
    {
        if ( !$this->cancelled )
        {
            if ( $node !== null )
            {
                foreach ( $this->plugins as $plugin )
                {
                    $plugin->afterNodeExecuted( $this, $node );
                }
            }

            $this->ended     = true;
            $this->resumed   = false;
            $this->suspended = false;

            $this->doEnd();
            $this->saveToVariableHandlers();

            if ( $node !== null )
            {
                $this->endThread( $node->getThreadId() );

                foreach ( $this->plugins as $plugin )
                {
                    $plugin->afterExecutionEnded( $this );
                }
            }
        }
        else
        {
            foreach ( $this->plugins as $plugin )
            {
                $plugin->afterExecutionCancelled( $this );
            }
        }
    }

    /**
     * The workflow engine's main execution loop. It is started by start() and
     * resume().
     *
     * @ignore
     */
    protected function execute()
    {
        // Try to execute nodes while there are executable nodes on the stack.
        do
        {
            // Flag that indicates whether a node has been executed during the
            // current iteration of the loop.
            $executed = false;

            // Iterate the stack of activated nodes.
            foreach ( $this->activatedNodes as $key => $node )
            {
                // Only try to execute a node if the execution of the
                // workflow instance has not ended yet.
                if ( $this->cancelled && $this->ended )
                {
                    // @codeCoverageIgnoreStart
                    break;
                    // @codeCoverageIgnoreEnd
                }

                // The current node is an end node but there are still
                // activated nodes on the stack.
                if ( $node  instanceof ezcWorkflowNodeEnd &&
                     !$node instanceof ezcWorkflowNodeCancel &&
                     $this->numActivatedNodes != $this->numActivatedEndNodes )
                {
                    continue;
                }

                // Execute the current node and check whether it finished
                // executing.
                if ( $node->execute( $this ) )
                {
                    // Remove current node from the stack of activated
                    // nodes.
                    unset( $this->activatedNodes[$key] );
                    $this->numActivatedNodes--;

                    // Notify plugins that the node has been executed.
                    if ( !$this->cancelled && !$this->ended )
                    {
                        foreach ( $this->plugins as $plugin )
                        {
                            $plugin->afterNodeExecuted( $this, $node );
                        }
                    }

                    // Toggle flag (see above).
                    $executed = true;
                }
            }
        }
        while ( !empty( $this->activatedNodes ) && $executed );

        // The stack of activated nodes is not empty but at the moment none of
        // its nodes can be executed.
        if ( !$this->cancelled && !$this->ended )
        {
            $this->suspend();
        }
    }

    /**
     * Activates a node and returns true if it was activated, false if not.
     *
     * The node will only be activated if the node is executable.
     * See {@link ezcWorkflowNode::isExecutable()}.
     *
     * @param ezcWorkflowNode $node
     * @param bool            $notifyPlugins
     * @return bool
     * @ignore
     */
    public function activate( ezcWorkflowNode $node, $notifyPlugins = true )
    {
        // Only activate the node when
        //  - the execution of the workflow has not been cancelled,
        //  - the node is ready to be activated,
        //  - and the node is not already activated.
        if ( $this->cancelled ||
             !$node->isExecutable() ||
             ezcWorkflowUtil::findObject( $this->activatedNodes, $node ) !== false )
        {
            return false;
        }

        $activateNode = true;

        foreach ( $this->plugins as $plugin )
        {
            $activateNode = $plugin->beforeNodeActivated( $this, $node );

            if ( !$activateNode )
            {
            // @codeCoverageIgnoreStart
                break;
            // @codeCoverageIgnoreEnd
            }
        }

        if ( $activateNode )
        {
            // Add node to list of activated nodes.
            $this->activatedNodes[] = $node;
            $this->numActivatedNodes++;

            if ( $node instanceof ezcWorkflowNodeEnd )
            {
                $this->numActivatedEndNodes++;
            }

            if ( $notifyPlugins )
            {
                foreach ( $this->plugins as $plugin )
                {
                    $plugin->afterNodeActivated( $this, $node );
                }
            }

            return true;
        }
        else
        {
            // @codeCoverageIgnoreStart
            return false;
            // @codeCoverageIgnoreEnd
        }
    }

    /**
     * Adds a variable that an (input) node is waiting for.
     *
     * @param ezcWorkflowNode $node
     * @param string $variableName
     * @param ezcWorkflowCondition $condition
     * @ignore
     */
    public function addWaitingFor( ezcWorkflowNode $node, $variableName, ezcWorkflowCondition $condition )
    {
        if ( !isset( $this->waitingFor[$variableName] ) )
        {
            $this->waitingFor[$variableName] = array(
              'node' => $node->getId(),
              'condition' => $condition
            );
        }
    }

    /**
     * Returns the variables that (input) nodes are waiting for.
     *
     * @return array
     * @ignore
     */
    public function getWaitingFor()
    {
        return $this->waitingFor;
    }

    /**
     * Start a new thread and returns the id of the new thread.
     *
     * @param int $parentId The id of the parent thread.
     * @param int $numSiblings The number of threads that are started by the same node.
     * @return int
     * @ignore
     */
    public function startThread( $parentId = null, $numSiblings = 1 )
    {
        if ( !$this->cancelled )
        {
            $this->threads[$this->nextThreadId] = array(
              'parentId' => $parentId,
              'numSiblings' => $numSiblings
            );

            foreach ( $this->plugins as $plugin )
            {
                $plugin->afterThreadStarted( $this, $this->nextThreadId, $parentId, $numSiblings );
            }

            return $this->nextThreadId++;
        }

        return false;
    }

    /**
     * Ends the thread with id $threadId
     *
     * @param  integer $threadId
     * @ignore
     */
    public function endThread( $threadId )
    {
        if ( isset( $this->threads[$threadId] ) )
        {
            unset( $this->threads[$threadId] );

            foreach ( $this->plugins as $plugin )
            {
                $plugin->afterThreadEnded( $this, $threadId );
            }
        }
        else
        {
            throw new ezcWorkflowExecutionException(
              sprintf(
                'There is no thread with id #%d.',
                $threadId
              )
            );
        }
    }

    /**
     * Returns a new execution object for a sub workflow.
     *
     * If this method is used to resume a subworkflow you must provide
     * the execution id through $id.
     *
     * If $interactive is false an ezcWorkflowExecutionNonInteractive
     * will be returned.
     *
     * This method can be used by nodes implementing sub-workflows
     * to get a new execution environment for the subworkflow.
     *
     * @param  int $id
     * @param  bool $interactive
     * @return ezcWorkflowExecution
     * @ignore
     */
    public function getSubExecution( $id = null, $interactive = true )
    {
        if ( $interactive )
        {
            $execution = $this->doGetSubExecution( $id );
        }
        else
        {
            $execution = new ezcWorkflowExecutionNonInteractive;
        }

        foreach ( $this->plugins as $plugin )
        {
            $execution->addPlugin( $plugin );
        }

        return $execution;
    }

    /**
     * Returns the number of siblings for a given thread.
     *
     * @param  int $threadId The id of the thread for which to return the number of siblings.
     * @return int
     * @ignore
     */
    public function getNumSiblingThreads( $threadId )
    {
        if ( isset( $this->threads[$threadId] ) )
        {
            return $this->threads[$threadId]['numSiblings'];
        }
        else
        {
            return false;
        }
    }

    /**
     * Returns the id of the parent thread for a given thread.
     *
     * @param  int $threadId The id of the thread for which to return the parent thread id.
     * @return int
     * @ignore
     */
    public function getParentThreadId( $threadId )
    {
        if ( isset( $this->threads[$threadId] ) )
        {
            return $this->threads[$threadId]['parentId'];
        }
        else
        {
            return false;
        }
    }

    /**
     * Adds a plugin to this execution.
     *
     * @param ezcWorkflowExecutionPlugin $plugin
     * @return bool true when the plugin was added, false otherwise.
     */
    public function addPlugin( ezcWorkflowExecutionPlugin $plugin )
    {
        $pluginClass = get_class( $plugin );

        if ( !isset( $this->plugins[$pluginClass] ) )
        {
            $this->plugins[$pluginClass] = $plugin;

            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Removes a plugin from this execution.
     *
     * @param ezcWorkflowExecutionPlugin $plugin
     * @return bool true when the plugin was removed, false otherwise.
     */
    public function removePlugin( ezcWorkflowExecutionPlugin $plugin )
    {
        $pluginClass = get_class( $plugin );

        if ( isset( $this->plugins[$pluginClass] ) )
        {
            unset( $this->plugins[$pluginClass] );

            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Adds a listener to this execution.
     *
     * @param ezcWorkflowExecutionListener $listener
     * @return bool true when the listener was added, false otherwise.
     */
    public function addListener( ezcWorkflowExecutionListener $listener )
    {
        if ( !isset( $this->plugins['ezcWorkflowExecutionListenerPlugin'] ) )
        {
            $this->addPlugin( new ezcWorkflowExecutionListenerPlugin );
        }

        return $this->plugins['ezcWorkflowExecutionListenerPlugin']->addListener( $listener );
    }

    /**
     * Removes a listener from this execution.
     *
     * @param ezcWorkflowExecutionListener $listener
     * @return bool true when the listener was removed, false otherwise.
     */
    public function removeListener( ezcWorkflowExecutionListener $listener )
    {
        if ( isset( $this->plugins['ezcWorkflowExecutionListenerPlugin'] ) )
        {
            return $this->plugins['ezcWorkflowExecutionListenerPlugin']->removeListener( $listener );
        }

        return false;
    }

    /**
     * Returns the activated nodes.
     *
     * @return array
     * @ignore
     */
    public function getActivatedNodes()
    {
        return $this->activatedNodes;
    }

    /**
     * Returns the execution ID.
     *
     * @return int
     * @ignore
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Returns a variable.
     *
     * @param string $variableName
     * @ignore
     */
    public function getVariable( $variableName )
    {
        if ( array_key_exists( $variableName, $this->variables ) )
        {
            return $this->variables[$variableName];
        }
        else
        {
            throw new ezcWorkflowExecutionException(
              sprintf(
                'Variable "%s" does not exist.',
                $variableName
              )
            );
        }
    }

    /**
     * Returns the variables.
     *
     * @return array
     * @ignore
     */
    public function getVariables()
    {
        return $this->variables;
    }

    /**
     * Checks whether or not a workflow variable has been set.
     *
     * @param string $variableName
     * @return bool true when the variable exists and false otherwise.
     * @ignore
     */
    public function hasVariable( $variableName )
    {
        return array_key_exists( $variableName, $this->variables );
    }

    /**
     * Sets a variable.
     *
     * @param  string $variableName
     * @param  mixed  $value
     * @return mixed the value that the variable has been set to
     * @ignore
     */
    public function setVariable( $variableName, $value )
    {
        foreach ( $this->plugins as $plugin )
        {
            $value = $plugin->beforeVariableSet( $this, $variableName, $value );
        }

        $this->variables[$variableName] = $value;

        foreach ( $this->plugins as $plugin )
        {
            $plugin->afterVariableSet( $this, $variableName, $value );
        }

        return $value;
    }

    /**
     * Sets the variables.
     *
     * @param array $variables
     * @ignore
     */
    public function setVariables( array $variables )
    {
        $this->variables = array();

        foreach ( $variables as $variableName => $value )
        {
            $this->setVariable( $variableName, $value );
        }
    }

    /**
     * Unsets a variable.
     *
     * @param  string $variableName
     * @return true, when the variable has been unset, false otherwise
     * @ignore
     */
    public function unsetVariable( $variableName )
    {
        $unsetVariable = true;

        if ( array_key_exists( $variableName, $this->variables ) )
        {
            foreach ( $this->plugins as $plugin )
            {
                $unsetVariable = $plugin->beforeVariableUnset( $this, $variableName );

                if ( !$unsetVariable )
                {
                    break;
                }
            }

            if ( $unsetVariable )
            {
                unset( $this->variables[$variableName] );

                foreach ( $this->plugins as $plugin )
                {
                    $plugin->afterVariableUnset( $this, $variableName );
                }
            }
        }

        return $unsetVariable;
    }

    /**
     * Returns true when the workflow execution has been cancelled.
     *
     * @return bool
     */
    public function isCancelled()
    {
        return $this->cancelled;
    }

    /**
     * Returns true when the workflow execution has ended.
     *
     * @return bool
     */
    public function hasEnded()
    {
        return $this->ended;
    }

    /**
     * Returns true when the workflow execution has been resumed.
     *
     * @return bool
     * @ignore
     */
    public function isResumed()
    {
        return $this->resumed;
    }

    /**
     * Returns true when the workflow execution has been suspended.
     *
     * @return bool
     */
    public function isSuspended()
    {
        return $this->suspended;
    }

    /**
     * Loads data from variable handlers and
     * merge it with the current execution data.
     */
    protected function loadFromVariableHandlers()
    {
        foreach ( $this->workflow->getVariableHandlers() as $variableName => $className )
        {
            $object = new $className;
            $this->setVariable( $variableName, $object->load( $this, $variableName ) );
        }
    }

    /**
     * Saves data to execution data handlers.
     */
    protected function saveToVariableHandlers()
    {
        foreach ( $this->workflow->getVariableHandlers() as $variableName => $className )
        {
            if ( isset( $this->variables[$variableName] ) )
            {
                $object = new $className;
                $object->save( $this, $variableName, $this->variables[$variableName] );
            }
        }
    }

    /**
     * Called by start() when workflow execution is initiated.
     *
     * Reimplementations can use this method to store workflow information
     * to a persistent medium when execution is started.
     *
     * @param  integer $parentId
     */
    abstract protected function doStart( $parentId );

    /**
     * Called by suspend() when workflow execution is suspended.
     *
     * Reimplementations can use this method to variable and node information
     * to a persistent medium.
     */
    abstract protected function doSuspend();

    /**
     * Called by resume() when workflow execution is resumed.
     *
     * Reimplementations can use this method to fetch execution
     * data if necessary..
     */
    abstract protected function doResume();

    /**
     * Called by end() when workflow execution is ended.
     *
     * Reimplementations can use this method to remove execution
     * data from the persistent medium.
     */
    abstract protected function doEnd();

    /**
     * Returns a new execution object for a sub workflow.
     *
     * Called by getSubExecution to get a new execution
     * environment for the new execution thread.
     *
     * Reimplementations must return a new execution
     * environment similar to themselves.
     *
     * @param  int $id
     * @return ezcWorkflowExecution
     */
    abstract protected function doGetSubExecution( $id = null );
}
?>
