package org.maachang.connector ;


/**
 * ConnectorService.
 * 
 * @version 2008/05/25
 * @author masahito suzuki
 * @since MaachangBase 1.00
 */
public class ConnectorService {
    
    /**
     * 受信スレッドサイズ.
     */
    private static final int RECV_THREAD = 3 ;
    
    /**
     * ConnectorAcceptThread.
     */
    private ConnectorAcceptThread accept = null ;
    
    /**
     * ConnectorReceiveThread.
     */
    private ConnectorReceiveThread[] receive = null ;
    
    /**
     * ConnectorPoolThread.
     */
    private ConnectorPoolThread[] pool = null ;
    
    private ConnectorService() {
        
    }
    
    /**
     * コンストラクタ.
     * @param headerBinary 通信内容を認証するヘッダを設定します.
     * @param callback コールバックサーバ実装を設定します.
     * @param manager ソケットマネージャを設定します.
     * @param poolLen プーリング長を設定します.
     * @exception Exception 例外.
     */
    public ConnectorService( byte[] headerBinary,ConnectorCallback callback,
        ConnectorManager manager,int poolLen )
        throws Exception {
        if( callback == null || manager.isClosed() == true || poolLen <= 0 ) {
            throw new IllegalArgumentException( "引数は不正です" ) ;
        }
        
        ConnectorQueue rq = new ConnectorQueue() ;
        ConnectorAcceptThread ac = new ConnectorAcceptThread( headerBinary,manager ) ;
        ConnectorReceiveThread[] rc = new ConnectorReceiveThread[ RECV_THREAD ] ;
        for( int i = 0 ; i < RECV_THREAD ; i ++ ) {
            rc[ i ] = new ConnectorReceiveThread( manager,rq ) ;
        }
        ConnectorPoolThread[] pt = new ConnectorPoolThread[ poolLen ] ;
        for( int i = 0 ; i < poolLen ; i ++ ) {
            pt[ i ] = new ConnectorPoolThread( headerBinary,manager,callback,rq ) ;
        }
        this.accept = ac ;
        this.receive = rc ;
        this.pool = pt ;
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        this.destroy() ;
    }
    
    /**
     * オブジェクト破棄.
     */
    public void destroy() {
        if( pool != null ) {
            int len = pool.length ;
            for( int i = 0 ; i < len ; i ++ ) {
                if( pool[ i ] != null ) {
                    pool[ i ].destroy() ;
                }
                pool[ i ] = null ;
            }
            pool = null ;
        }
        if( receive != null ) {
            int len = receive.length ;
            for( int i = 0 ; i < len ; i ++ ) {
                if( receive[ i ] != null ) {
                    receive[ i ].destroy() ;
                }
                receive[ i ] = null ;
            }
            receive = null ;
        }
        if( accept != null ) {
            accept.destroy() ;
            accept = null ;
        }
    }
}
