"use strict" ;

import logger from '../../logging/logger'

import ObjectFactory from '../../../system/ioc/ObjectFactory'
import Call          from '../../../system/process/Call'
import Chain         from '../../../system/process/Chain'
import TaskGroup     from '../../../system/process/TaskGroup'

import State     from '../State'
import StateTask from './StateTask'
import View      from '../View'

/**
 * Close a specific state.
 * @summary Close a specific state.
 * @name CloseState
 * @class
 * @memberof molecule.states.process
 * @implements molecule.states.process.StateTask
 * @constructs
 */
export default function CloseState( state = null , factory = null )
{
    StateTask.call( this , state , factory ) ;

    Object.defineProperties( this ,
    {
        /**
         * @private
         */
        _chain : { value : new Chain() }
    });

    this._chain.mode = TaskGroup.TRANSIENT ;
    this._chain.finishIt.connect( this.notifyFinished.bind(this) ) ;
}

CloseState.prototype = Object.create( StateTask.prototype ,
{
    constructor : { writable : true , value : CloseState } ,

    /**
     * Run the process.
     * @memberof molecule.states.process.CloseState
     * @instance
     * @function
     */
    run : { value : function( )
    {
        logger.debug( this + " run " + this.state ) ;

        this.notifyStarted() ;

        if ( !(this.state instanceof State) )
        {
            logger.warning(this + " failed, the State reference of this process not must be 'null'.") ;
            this.notifyFinished() ;
            return ;
        }

        let view = this.state.view ;

        if ( view instanceof String || (typeof(view) === 'string') && (this.factory instanceof ObjectFactory) )
        {
            view = this.factory.getObject( view ) ;
        }
        else
        {
            logger.warning( this + " run failed, the display of the state:" + this.state + " isn't register in the ioc factory with the view id : " + view ) ;
        }

        if ( view instanceof View )
        {
            if ( view.closeBefore )
            {
                this._chain.add( view.closeBefore ) ;
            }

            this._chain.add( new Call( view.close , view ) ) ;

            if ( view.closeAfter )
            {
                this._chain.add( view.closeAfter ) ;
            }
        }
        else
        {
            logger.warning( this + " failed, we can't find no View with the State : " + this.state ) ;
        }

        if ( ( this._chain.length > 0 ) && !this._chain.running )
        {
            this._chain.run() ;
        }
        else
        {
            this.notifyFinished() ;
        }
    }}
}) ;