package org.maachang.comet.conf ;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import org.maachang.comet.MaachangDef;
import org.maachang.conf.Config;
import org.maachang.conf.ReadIni;
import org.maachang.util.FileUtil;

/**
 * mime.conf用読み込みファイル.
 *
 * @version 2007/08/19
 * @author  masahito suzuki
 * @since   MaachangComet 1.00
 */
public class MimeConfig {
    
    /**
     * GZIP圧縮モード.
     */
    public static final String OPTION_GZIP = "gzip." ;
    
    /**
     * 読み込みファイル名.
     */
    private static final String READ_FILE = MaachangDef.DIRECTORY_CONFIG+"mime.conf" ;
    
    /**
     * キャラクタセット.
     */
    private static final String CHARSET = "UTF8" ;
    
    /**
     * 基本セクション名.
     */
    private static final String BASE_SECTION = "mime-type" ;
    
    /**
     * 基本MimeType.
     */
    private static final String DEFAULT_MIME_TYPE = "application/octet-stream" ;
    
    /**
     * 読み込み対象データ.
     */
    private Config iniParams = null ;
    
    /**
     * 対象ファイル.
     */
    private String fileName = null ;
    
    /**
     * 最終更新日.
     */
    private long lastUpdate = -1L ;
    
    /**
     * コンストラクタ.
     */
    public MimeConfig() {
        
    }
    
    /**
     * オープン.
     * <BR><BR>
     * オープンします.
     * <BR>
     * @exception Exception 例外.
     */
    public synchronized void open() throws Exception {
        this.open( READ_FILE ) ;
    }
    
    /**
     * オープン.
     * <BR><BR>
     * オープンします.
     * <BR>
     * @param name 対象のファイル名を設定します.
     * @exception Exception 例外.
     */
    public synchronized void open( String name ) throws Exception {
        this.fileName = FileUtil.getFullPath( name ) ;
        try {
            this.reload() ;
        } catch( Exception e ) {
            this.close() ;
            throw e ;
        } finally {
        }
    }
    
    /**
     * クローズ.
     * <BR><BR>
     * クローズ処理.
     */
    public synchronized void close() {
        iniParams = null ;
        fileName = null ;
        lastUpdate = -1L ;
    }
    
    /**
     * 指定名の条件を取得.
     * <BR><BR>
     * 指定名の条件を取得します.
     * <BR>
     * @param name 対象の名前を設定します.
     * @return String 対象の条件が返されます.
     */
    public synchronized String get( String name ) {
        try {
            long tm = FileUtil.getLastTime( fileName ) ;
            if( lastUpdate != tm ) {
                this.reload() ;
            }
        } catch( Exception e ) {
        }
        return iniParams.get( BASE_SECTION,name,0 ) ;
    }
    
    /**
     * 指定Mimeタイプの条件を取得.
     * <BR><BR>
     * 指定ファイル名を設定して、Mimeタイプを取得します.
     * <BR>
     * @param name 対象名を設定します.
     * @return String 対象MimeTypeが返されます.
     */
    public synchronized String getNameByMimeType( String name ) {
        try {
            long tm = FileUtil.getLastTime( fileName ) ;
            if( lastUpdate != tm ) {
                this.reload() ;
            }
        } catch( Exception e ) {
        }
        String plus = getPlus( name ) ;
        if( plus == null ) {
            plus = name ;
        }
        String ret = iniParams.get( BASE_SECTION,plus,0 ) ;
        if( ret == null ) {
            ret = DEFAULT_MIME_TYPE ;
        }
        return ret ;
    }
    
    /**
     * 再読み込み.
     */
    private final void reload()
        throws Exception {
        BufferedReader buf = null ;
        if( FileUtil.isFileExists( fileName ) == true ) {
            try {
                buf = new BufferedReader(
                    new InputStreamReader(
                        new FileInputStream( fileName ),CHARSET ) ) ;
                Config iniParams = new Config() ;
                ReadIni.analisys( iniParams,buf ) ;
                buf.close() ;
                buf = null ;
                long last = FileUtil.getLastTime( fileName ) ;
                // 読み込みデータを設定.
                this.iniParams = iniParams ;
                this.lastUpdate = last ;
            } catch( Exception e ) {
                throw e ;
            } finally {
                if( buf != null ) {
                    try {
                        buf.close() ;
                    } catch( Exception e ) {
                    }
                }
            }
        }
    }
    
    /**
     * 拡張子を取得.
     */
    private static final String getPlus( String name ) {
        int p = name.lastIndexOf( "." ) ;
        if( p == -1 ) {
            return null ;
        }
        return name.substring( p+1,name.length() ) ;
    }
    
    /**
     * 文字列に変換.
     */
    public String toString() {
        if( iniParams != null ) {
            return iniParams.toString() ;
        }
        return "null" ;
    }
}

