package org.maachang.session.server ;

import java.io.IOException;
import java.net.InetAddress;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.conf.Config;
import org.maachang.conf.ReadConfigUtil;
import org.maachang.connector.ConnectorManager;
import org.maachang.connector.ConnectorService;
import org.maachang.session.engine.PersistenceDefine;
import org.maachang.session.engine.PersistenceEngine;
import org.maachang.session.engine.PersistenceService;


/**
 * PersistenceSessionサーバサービス.
 * 
 * @version 2008/05/25
 * @author masahito suzuki
 * @since PersistenceSession 1.00
 */
public class PSessionServerService {
    
    /**
     * ログ出力.
     */
    private static final Log LOG = LogFactory.getLog( PSessionServerService.class ) ;
    
    /**
     * セッションコンフィグファイル名.
     */
    private static final String SESSION_CONFIG = "./conf/session.conf" ;
    
    /**
     * コネクターサービス.
     */
    private ConnectorService service = null ;
    
    /**
     * コンストラクタ.
     */
    public PSessionServerService() throws Exception {
        Config conf = readConfig() ;
        InetAddress addr = conf.getInetAddress( "session-net","bind-addr",0 ) ;
        int port = conf.getInt( "session-net","bind-port",0 ) ;
        int max = conf.getInt( "session-net","max",0 ) ;
        int pool = conf.getInt( "session-net","thread",0 ) ;
        createObject( addr,port,max,pool ) ;
    }
    
    /**
     * コンストラクタ.
     * @param addr 対象のバインドアドレスを設定します.
     * @param port 対象のバインドポートを設定します.
     * @param max 対象の最大接続数を設定します.
     * @param pool 対象のプーリング数を設定します.
     * @exception Exception 例外.
     */
    public PSessionServerService( InetAddress addr,int port,int max,int pool )
        throws Exception {
        createObject( addr,port,max,pool ) ;
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        destroy() ;
    }
    
    /**
     * オブジェクトを破棄.
     */
    public void destroy() {
        if( service != null ) {
            LOG.info( "## PSessionServerService - 破棄" ) ;
            service.destroy() ;
        }
    }
    
    /**
     * コンフィグ情報を取得.
     * @return Config コンフィグ情報が返されます.
     * @exception Exception 例外
     */
    public static final Config readConfig() throws Exception {
        Config conf = new Config() ;
        ReadConfigUtil.readConfig( conf,SESSION_CONFIG ) ;
        return conf ;
    }
    
    /**
     * オブジェクト生成.
     */
    private void createObject( InetAddress addr,int port,int max,int pool )
        throws Exception {
        PersistenceEngine engine = PersistenceService.getInstance().getEngine() ;
        if( engine == null || engine.isUse() == false ) {
            throw new IOException( "PersistenceServiceが開始されていません" ) ;
        }
        if( port <= -1 || port >= 65536 ) {
            port = PersistenceDefine.BIND_PORT ;
        }
        if( max <= 0 ) {
            max = PersistenceDefine.MAX_CONNECT ;
        }
        if( pool <= 0 ) {
            pool = PersistenceDefine.POOL_LENGTH ;
        }
        if( addr != null ) {
            LOG.info( "## PSessionServerService - 生成[ addr:" + addr.getHostAddress() +
                " port:" + port + " max:" + max + " pool:" + pool + "]" ) ;
        }
        else {
            LOG.info( "## PSessionServerService - 生成[ addr:0.0.0.0" +
                " port:" + port + " max:" + max + " pool:" + pool + "]" ) ;
        }
        ConnectorManager man = new ConnectorManager( addr,port,max ) ;
        PSessionCallback call = new PSessionCallback( engine ) ;
        ConnectorService sv = new ConnectorService( PersistenceDefine.PROTOCOL_HEADER,
            call,man,pool ) ;
        this.service = sv ;
    }
}
