package org.maachang.comet;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.comet.conf.IniFile;
import org.maachang.comet.conf.StartupConfig;
import org.maachang.comet.down.ShutdownServer;
import org.maachang.comet.httpd.HttpdVersionDef;
import org.maachang.comet.httpd.engine.StartupHttpdEngine;
import org.maachang.comet.httpd.engine.script.ExecutionStartup;
import org.maachang.jsr.script.api.ApiManager;
import org.maachang.manager.GlobalManager;
import org.maachang.shutdown.ShutdownHook;
import org.maachang.shutdown.WaitShutdown;

/**
 * MaachangComet開始処理.
 * 
 * @version 2007/08/26
 * @author masahito suzuki
 * @since MaachangComet 1.00
 */
public class Startup {
    
    /**
     * LOG.
     */
    private static final Log LOG = LogFactory.getLog( Startup.class ) ;
    
    /**
     * コンストラクタ.
     */
    private Startup() {
        
    }
    
    /**
     * メインメソッド.
     * <BR><BR>
     * @param args Javaからのパラメータが設定されます.
     * @exception Exception 例外.
     */
    public static final void main( String[] args )
        throws Exception {
        new Startup().execution( args ) ;
    }
    
    /**
     * 実行処理.
     */
    private void execution( String[] args )
        throws Exception {
        String path = "." ;
        long tm = System.currentTimeMillis() ;
        try {
            State.getInstance().state( State.START_UP ) ;// 起動中に設定.
            // 開始処理.
            LOG.info( "*** maachang comet - webapps .. " ) ;
            LOG.info( "*** [ver."+HttpdVersionDef.getVersion()+" update."+HttpdVersionDef.getDate()+"]" ) ;
            LOG.info( "***" ) ;
            
            ScriptEngineFactory fac = null ;
            if( ApiManager.getInstance() != null ) {
                ScriptEngine eng = ApiManager.getInstance().getScriptEngine() ;
                if( eng != null ) {
                    fac = eng.getFactory() ;
                }
                eng = null ;
            }
            if( fac == null ) {
                LOG.error( "*** no-javascript suport!!" ) ;
                return ;
            }
            LOG.info( "*** engineName:" + fac.getEngineName() ) ;
            LOG.info( "*** engineVersion:" + fac.getEngineVersion() ) ;
            LOG.info( "***" ) ;
            fac = null ;
            
            LOG.info( "*** startupConfig....[START]" ) ;
            StartupConfig.init( path ) ;
            LOG.info( "*** startupConfig....[END]" ) ;
            LOG.info( "*** startupHttpd.....[START]" ) ;
            StartupHttpdEngine.init( path ) ;
            LOG.info( "*** startupHttpd.....[END]" ) ;
            LOG.info( "*** startupScript....[START]" ) ;
            ExecutionStartup.init() ;
            LOG.info( "*** startupScript....[END]" ) ;
            
            LOG.info( "### startup....[END:" + ( System.currentTimeMillis() - tm ) + "ms]" ) ;
            State.getInstance().state( State.SUCCESS ) ;// 起動完了に設定.
            
            // シャットダウンフックを登録.
            ShutdownHook.registHook( new ShutdownServer() ) ;
            
            // シャットダウン待ちオブジェクトを生成.
            WaitShutdown waitDown = new WaitShutdown( shutdownPort() ) ;
            
            // 終了待ち.
            for( ;; ) {
                if( waitDown.isShutdown() ) {
                    LOG.info( "*** maachang comet - start shutdown " ) ;
                    waitDown.exitShutdown() ;
                    LOG.info( "*** maachang comet - shutdown ..... end " ) ;
                    break ;
                }
            }
        } catch( Exception e ) {
            LOG.error( "### error",e ) ;
        }
    }
    
    /**
     * シャットダウン待ちポート番号を取得.
     */
    private static final int shutdownPort() {
        int ret = -1 ;
        GlobalManager nm = GlobalManager.getInstance() ;
        IniFile conf = ( IniFile )nm.get( ServiceDef.MANAGER_BY_CONFIG ) ;
        if( conf != null ) {
            Object o = conf.get( "server","shutdown-port",0 ) ;
            if( o != null ) {
                try {
                    ret = Integer.parseInt( ( String )o ) ;
                } catch( Exception e ) {
                    ret = -1 ;
                }
            }
        }
        return ret ;
    }
}
