package org.maachang.proxy;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.proxy.down.ShutdownCallback;
import org.maachang.proxy.down.ShutdownHook;
import org.maachang.proxy.down.WaitShutdown;
import org.maachang.proxy.engine.EngineService;
import org.maachang.proxy.engine.VersionDef;
import org.maachang.proxy.engine.error.ErrorPageManager;
import org.maachang.util.FileUtil;
import org.maachang.util.conf.Config;
import org.maachang.util.conf.ReadIni;

/**
 * MaachangProxy.
 * 
 * @version 2008/03/25
 * @author masahito suzuki
 * @since MaachangProxy 1.00
 */
public class MaachangProxy {
    private static final String CONF = "conf/" ;
    private static final String SERVER_CONF = CONF + "server.conf" ;
    private static final String SSL_CONF = CONF + "ssl.conf" ;
    private static final Log LOG = LogFactory.getLog( MaachangProxy.class ) ;
    
    /** メイン処理 */
    public static final void main( String[] args ) throws Exception {
        new MaachangProxy().execution( args ) ;
    }
    
    /** 実行処理. */
    private final void execution( String[] args ) throws Exception {
        if( LOG.isInfoEnabled() ) {
            LOG.info( "** startup MaachangProxy["+VersionDef.getVersion() +"] **" ) ;
        }
        initErrorPage() ;
        Config serverConfig = getConfig( SERVER_CONF ) ;
        EngineService service = new EngineService(
            serverConfig,
            getConfig( SSL_CONF ) ) ;
        ShutdownHook hook = ShutdownHook.registHook( new ProxyShutdown( service ) ) ;
        WaitShutdown waitDown = new WaitShutdown( getShutdownPort( serverConfig ) ) ;
        for( ;; ) {
            if( service.isUse() == false || waitDown.isShutdown() ) {
                hook.getShutdownCallback().execution() ;
                waitDown.exitShutdown() ;
                break ;
            }
        }
    }
    
    /** コンフィグファイルを取得. */
    protected static final Config getConfig( String name ) throws Exception {
        BufferedReader r = null ;
        try {
            Config ret = new Config() ;
            r = new BufferedReader( new InputStreamReader( new FileInputStream( name ),"UTF8" ) ) ;
            ReadIni.analisys( ret,r ) ;
            r.close() ;
            r = null ;
            return ret ;
        } finally {
            if( r != null ) {
                try {
                    r.close() ;
                } catch( Exception e ) {
                }
            }
        }
    }
    
    /** エラーページを初期化 */
    private static final void initErrorPage() throws Exception {
        String dir = FileUtil.getFullPath( "." ) ;
        ErrorPageManager man = ErrorPageManager.getInstance() ;
        man.create( dir ) ;
    }
    
    /** シャットダウンポートを取得. */
    protected static final int getShutdownPort( Config conf ) throws Exception {
        if( conf == null ) {
            conf = getConfig( SERVER_CONF ) ;
        }
        return conf.getInt( "server","shutdown-port",0 ) ;
    }
}

/**
 * シャットダウン用コールバック.
 */
class ProxyShutdown extends ShutdownCallback {
    private static final Log LOG = LogFactory.getLog( ProxyShutdown.class ) ;
    private EngineService service = null ;
    public ProxyShutdown( EngineService service ) {
        this.service = service ;
    }
    public void execution() {
        LOG.info( "** shutdown MaachangProxy["+VersionDef.getVersion() +"] **" ) ;
        if( this.service != null ) {
            this.service.close() ;
        }
    }
}

