package org.maachang.proxy.engine.conf;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import org.maachang.proxy.engine.net.RequestInfo;
import org.maachang.proxy.engine.net.ResponseInfo;
import org.maachang.util.Roll;

/**
 * アクセス管理.
 * 
 * @version 2008/04/10
 * @author masahito suzuki
 * @since MaachangProxy 1.01
 */
public class AccessManager implements Serializable {
    private static final long serialVersionUID = -1100676817608904943L;

    /**
     * アクセス管理最大数.
     */
    private static final int MAX_LENGTH = 100 ;
    
    /**
     * アクセス管理データ.
     */
    private Roll manager = null ;
    
    /**
     * コンストラクタ.
     */
    public AccessManager() throws Exception {
        manager = new Roll( MAX_LENGTH ) ;
    }
    
    /**
     * アクセス結果を追加.
     * @param host 対象のホスト名を設定します.
     * @param request 対象のリクエストを設定します.
     */
    public void add( String host,String addr,RequestInfo req,ResponseInfo res ) {
        try {
            if( host == null || addr == null || req == null || res == null ) {
                return ;
            }
            String type = res.getHeader( "Content-Type",0 ) ;
            if( type == null ) {
                return ;
            }
            if( type.indexOf( "text/html" ) <= -1 &&
                type.indexOf( "application/xhtml" ) <= -1 &&
                type.indexOf( "text/xml" ) <= -1 && 
                type.indexOf( "text/plain" ) <= -1 ) {
                return ;
            }
            AccessInfo info = new AccessInfo() ;
            info.setUrl( host + req.getUrl() ) ;
            info.setAddr( addr ) ;
            info.setUserAgent( req.getHeader( "User-Agent",0 ) ) ;
            info.setState( res.getState() ) ;
            info.setDate( new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" ).format( new Date() ) ) ;
            synchronized( this ) {
                if( manager.add( info ) == false ) {
                    manager.get() ;
                    manager.add( info ) ;
                }
            }
        } catch( Exception e ) {
        }
    }
    
    /**
     * アクセス内容を取得.
     * @return ArrayList<AccessInfo> 現在のアクセス内容が返されます.
     */
    public ArrayList<AccessInfo> get() {
        ArrayList<AccessInfo> ret = new ArrayList<AccessInfo>() ;
        synchronized( this ) {
            for( int i = 0 ; i < MAX_LENGTH ; i ++ ) {
                AccessInfo info = ( AccessInfo )manager.reference( i ) ;
                if( info == null ) {
                    break ;
                }
                ret.add( info ) ;
            }
        }
        return ret ;
    }
}
