package org.maachang.comet.net ;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.channels.ServerSocketChannel;

/**
 * サーバソケット.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
class NetServerImpl implements HttpServer {
    
    private static final int DEFAULT_PORT = 3333 ;
    protected static final int MIN_LENGTH = 1 ;
    protected static final int MAX_LENGTH = 50000 ;
    private ServerSocket serverSocket = null ;
    
    private NetServerImpl() { }
    
    public NetServerImpl( int port,int backlog )
        throws Exception {
        this( null,port,backlog ) ;
    }
    
    public NetServerImpl( InetAddress addr,int port,int backlog )
        throws Exception {
        if( backlog <= MIN_LENGTH ) {
            backlog = MIN_LENGTH ;
        }
        else if( backlog > MAX_LENGTH ) {
            backlog = MAX_LENGTH ;
        }
        if( port <= 0 || port > 65535 ) {
            port = DEFAULT_PORT ;
        }
        ServerSocket server = ServerSocketChannel.open().socket() ;
        server.getChannel().configureBlocking(false);
        server.setReuseAddress( true ) ;
        if( addr == null ) {
            server.bind( new InetSocketAddress( port ),backlog ) ;
        }
        else {
            server.bind( new InetSocketAddress( addr,port ),backlog ) ;
        }
        this.serverSocket = server ;
    }
    
    protected void finalize() throws Exception {
        this.destroy() ;
    }
    
    public void destroy() {
        if( this.serverSocket != null ) {
            try {
                this.serverSocket.close() ;
            } catch( Exception e ) {
            }
        }
        this.serverSocket = null ;
    }
    
    public ServerSocketChannel channel() {
        if( isClosed() ) {
            return null ;
        }
        return serverSocket.getChannel() ;
    }
    
    public Object option() {
        return null ;
    }

    
    public boolean isClosed() {
        boolean ret = false ;
        try {
            if( this.serverSocket == null ||
                this.serverSocket.isBound() == false ||
                this.serverSocket.isClosed() == true ) {
                ret = true ;
            }
        } catch( Exception e ) {
            ret = true ;
        }
        return ret ;
    }
    
}
