package org.maachang.comet.net ;

import java.net.InetAddress;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.maachang.comet.net.nio.HttpReceiveCallback;
import org.maachang.comet.net.nio.NioService;
import org.maachang.comet.net.ssl.SslOption;

/**
 * ネットワークサービス.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
public class NetService {
    
    private static final Log LOG = LogFactory.getLog( NetService.class ) ;
    
    private NetServerImpl http = null ;
    private NetSslServerImpl ssl = null ;
    private NioService nioService = null ;
    
    /**
     * コンストラクタ.
     */
    public NetService() {
        
    }
    
    /**
     * デストラクタ.
     */
    protected void finalize() throws Exception {
        this.close() ;
    }
    
    /**
     * オープン.
     * <BR><BR>
     * NetServiceをオープンします.
     * <BR>
     * @param executionObject 受信コールバックオブジェクトを設定します.
     * @param opt SSLオプションを設定します.
     * @param maxConnect 最大コネクション数を設定します.
     * @param length Threadプーリング数を設定します.
     * @param port サーバポート番号を設定します.
     * @exception Exception 例外.
     */
    public void open( HttpReceiveCallback call,SslOption opt,int maxConnect,int length,int port )
        throws Exception {
        this.open( call,opt,maxConnect,length,null,port ) ;
    }
    
    /**
     * オープン.
     * <BR><BR>
     * NetServiceをオープンします.
     * <BR>
     * @param call 受信コールバックオブジェクトを設定します.
     * @param opt SSLオプションを設定します.
     * @param maxConnect 最大コネクション数を設定します.
     * @param length Threadプーリング数を設定します.
     * @param addr サーバアドレスを設定します.
     * @param port サーバポート番号を設定します.
     * @exception Exception 例外.
     */
    public void open( HttpReceiveCallback call,SslOption opt,int maxConnect,int length,InetAddress addr,int port )
        throws Exception {
        if( call == null ) {
            throw new IllegalArgumentException( "対象条件は不正です" ) ;
        }
        this.close() ;
        try {
            int sslCon = -1 ;
            if( opt != null ) {
                sslCon = maxConnect / 4 ;
                if( sslCon <= 0 ) {
                    sslCon = 1 ;
                }
                maxConnect -= sslCon ;
            }
            this.http = new NetServerImpl( addr,port,maxConnect ) ;
            if( sslCon > 0 ) {
                this.ssl = new NetSslServerImpl( opt,
                    opt.getSslAddress(),opt.getSslPort(),sslCon ) ;
            }
            else {
                this.ssl = null ;
            }
            this.nioService = new NioService() ;
            this.nioService.open( call,this.http,this.ssl,length ) ;
        } catch( Exception e ) {
            LOG.error( "## error",e ) ;
            this.close() ;
            throw e ;
        }
    }
    
    /**
     * クローズ処理.
     * <BR><BR>
     * NetServiceをクローズします.
     */
    public void close() {
        if( this.nioService != null ) {
            this.nioService.close() ;
        }
        if( this.ssl != null ) {
            this.ssl.destroy() ;
        }
        if( this.http != null ) {
            this.http.destroy() ;
        }
        this.nioService = null ;
        this.ssl = null ;
        this.http = null ;
    }
    
    /**
     * NIOサービスを取得.
     * @return NioService NIOサービスが返されます.
     */
    public NioService getNioService() {
        return nioService ;
    }
}
