package org.maachang.proxy.engine.conf;

import java.net.InetAddress;

import org.maachang.util.conf.Config;

/**
 * SSLオプション.
 * 
 * @version 2007/11/17
 * @author  masahito suzuki
 * @since MaachangProxy 1.00
 */
public class SslOption {
    
    /**
     * SSLセクション名.
     */
    private static final String SSL_SECTION = "ssl" ;
    
    /**
     * KeyStoreセクション名.
     */
    private static final String KEYSTORE_SECTION = "keystore" ;
    
    /**
     * TrustStoreセクション名.
     */
    private static final String TRUSTSTORE_SECTION = "truststore" ;
    
    /**
     * デフォルトストア.
     */
    public static final String DEFAULT_STORE = "JKS" ;
    
    /**
     * デフォルトマネージャアルゴリズム.
     */
    public static final String DEFAULT_MANAGER_ALGORITHM = "SunX509" ;
    
    /**
     * デフォルトSSLプロトコル.
     */
    public static final String DEFAULT_SSL_PROTOCOL = "TLS" ;
    
    /**
     * キーストアタイプ.
     */
    private String keyStore = DEFAULT_STORE ;
    
    /**
     * トラストストアタイプ.
     */
    private String trustStore = DEFAULT_STORE ;
    
    /**
     * キーストアパスワード.
     */
    private String keyStorePasswd = null ;
    
    /**
     * トラストストアパスワード.
     */
    private String trustPassword = null ;
    
    /**
     * キーストアマネージャアルゴリズム.
     */
    private String keyManagerAlgorithm = DEFAULT_MANAGER_ALGORITHM ;
    
    /**
     * トラストストアマネージャアルゴリズム.
     */
    private String trustKeyManagerAlgorithm = DEFAULT_MANAGER_ALGORITHM ;
    
    /**
     * SSLプロトコル.
     */
    private String sslProtocol = DEFAULT_SSL_PROTOCOL ;
    
    /**
     * 乱数アルゴリズム(PRNG).
     */
    private String randomAlgorithm = null ;
    
    /**
     * キーストアファイル名.
     */
    private String keyStoreFile = null ;
    
    /**
     * トラストストアキーファイル名.
     */
    private String trustFile = null ;
    
    /**
     * クライアント認証.
     */
    private boolean clientAuth = false ;
    
    /**
     * SSLポート番号.
     */
    private int sslPort = -1 ;
    
    /**
     * SSLアドレス.
     */
    private InetAddress sslAddress = null ;
    
    /**
     * コンストラクタ.
     */
    public SslOption() {
        
    }

    /**
     * コンフィグ情報から、SSLオプションを生成.
     * <BR>
     * @param conf 対象のコンフィグを設定します.
     * @return SslOption SSLオプションが返されます.
     */
    public static final SslOption create( Config conf ) {
        SslOption sslOpt = null ;
        if( conf.isSection( SSL_SECTION ) == true &&
            conf.getBoolean( SSL_SECTION,"ssl",0 ) == true ) {
            // SSLが有効.
            if( conf.isSection( KEYSTORE_SECTION ) == true &&
                conf.get( KEYSTORE_SECTION,"key-file",0 ) != null ) {
                sslOpt = new SslOption() ;
                Object val = null ;
                // ssl設定を取得.
                if( ( val = conf.getInetAddress( SSL_SECTION,"address",0 ) ) != null ) {
                    sslOpt.setSslAddress( ( InetAddress )val ) ;
                }
                if( ( val = conf.getInt( SSL_SECTION,"port",0 ) ) != null ) {
                    sslOpt.setSslPort( ( ( Integer )val ).intValue() ) ;
                }
                if( ( val = conf.get( SSL_SECTION,"protocol",0 ) ) != null ) {
                    sslOpt.setSslProtocol( ( String )val ) ;
                }
                if( ( val = conf.get( SSL_SECTION,"random-algorithm",0 ) ) != null ) {
                    sslOpt.setRandomAlgorithm( ( String )val ) ;
                }
                if( conf.getBoolean( SSL_SECTION,"client-auth",0 ) == true ) {
                    sslOpt.setClientAuth( true ) ;
                }
                // keystore情報を取得.
                if( ( val = conf.get( KEYSTORE_SECTION,"key-store",0 ) ) != null ) {
                    sslOpt.setKeyStore( ( String )val ) ;
                }
                if( ( val = conf.get( KEYSTORE_SECTION,"key-manager-algorithm",0 ) ) != null ) {
                    sslOpt.setKeyManagerAlgorithm( ( String )val ) ;
                }
                if( ( val = conf.get( KEYSTORE_SECTION,"key-passwd",0 ) ) != null ) {
                    sslOpt.setKeyStorePasswd( ( String )val ) ;
                }
                if( ( val = conf.get( KEYSTORE_SECTION,"key-file",0 ) ) != null ) {
                    sslOpt.setKeyStoreFile( ( String )val ) ;
                }
                // trustStore情報を取得.
                if( conf.isSection( TRUSTSTORE_SECTION ) == true &&
                    conf.getBoolean( TRUSTSTORE_SECTION,"trust",0 ) == true ) {
                    if( ( val = conf.get( TRUSTSTORE_SECTION,"trust-store",0 ) ) != null ) {
                        sslOpt.setTrustStore( ( String )val ) ;
                    }
                    if( ( val = conf.get( TRUSTSTORE_SECTION,"trust-manager-algorithm",0 ) ) != null ) {
                        sslOpt.setTrustKeyManagerAlgorithm( ( String )val ) ;
                    }
                    if( ( val = conf.get( TRUSTSTORE_SECTION,"trust-passwd",0 ) ) != null ) {
                        sslOpt.setTrustPassword( ( String )val ) ;
                    }
                    if( ( val = conf.get( TRUSTSTORE_SECTION,"trust-file",0 ) ) != null ) {
                        sslOpt.setTrustFile( ( String )val ) ;
                    }
                }
                else {
                    sslOpt.setTrustStore( null ) ;
                    sslOpt.setTrustPassword( null ) ;
                    sslOpt.setTrustKeyManagerAlgorithm( null ) ;
                    sslOpt.setTrustFile( null ) ;
                }
            }
        }
        return sslOpt ;
    }

    /**
     * キーストアマネージャアルゴリズム を取得.
     * <BR><BR>
     * @return キーストアマネージャアルゴリズム が返されます.
     */
    public String getKeyManagerAlgorithm() {
        return keyManagerAlgorithm;
    }

    /**
     * キーストアマネージャアルゴリズム を設定.
     * <BR><BR>
     * @param keyManagerAlgorithm キーストアマネージャアルゴリズム を設定します.
     */
    public void setKeyManagerAlgorithm(String keyManagerAlgorithm) {
        if( keyManagerAlgorithm == null ||
            ( keyManagerAlgorithm = keyManagerAlgorithm.trim() ).length() <= 0 ) {
            return ;
        }
        this.keyManagerAlgorithm = keyManagerAlgorithm;
    }

    /**
     * トラストストアマネージャアルゴリズム を取得.
     * <BR><BR>
     * @return トラストストアマネージャアルゴリズム が返されます.
     */
    public String getTrustKeyManagerAlgorithm() {
        return trustKeyManagerAlgorithm;
    }

    /**
     * トラストストアマネージャアルゴリズム を設定.
     * <BR><BR>
     * @param trustKeyManagerAlgorithm トラストストアマネージャアルゴリズム を設定します.
     */
    public void setTrustKeyManagerAlgorithm(String trustKeyManagerAlgorithm) {
        if( trustKeyManagerAlgorithm == null ||
            ( trustKeyManagerAlgorithm = trustKeyManagerAlgorithm.trim() ).length() <= 0 ) {
            return ;
        }
        this.trustKeyManagerAlgorithm = trustKeyManagerAlgorithm;
    }

    /**
     * キーストアタイプ を取得.
     * <BR><BR>
     * @return キーストアタイプ が返されます.
     */
    public String getKeyStore() {
        return keyStore;
    }

    /**
     * キーストアタイプ を設定.
     * <BR><BR>
     * @param keyStore キーストアタイプ を設定します.
     */
    public void setKeyStore(String keyStore) {
        if( keyStore == null ||
            ( keyStore = keyStore.trim() ).length() <= 0 ) {
            return ;
        }
        this.keyStore = keyStore;
    }

    /**
     * トラストストアタイプ を取得.
     * <BR><BR>
     * @return トラストストアタイプ が返されます.
     */
    public String getTrustStore() {
        return trustStore;
    }

    /**
     * トラストストアタイプ を設定.
     * <BR><BR>
     * @param trustStore トラストストアタイプ を設定します.
     */
    public void setTrustStore(String trustStore) {
        if( trustStore == null ||
            ( trustStore = trustStore.trim() ).length() <= 0 ) {
            return ;
        }
        this.trustStore = trustStore;
    }

    /**
     * キーストアファイル名 を取得.
     * <BR><BR>
     * @return キーストアファイル名 が返されます.
     */
    public String getKeyStoreFile() {
        return keyStoreFile;
    }

    /**
     * キーストアファイル名 を設定.
     * <BR><BR>
     * @param keyStoreFile キーストアファイル名 を設定します.
     */
    public void setKeyStoreFile(String keyStoreFile) {
        if( keyStoreFile == null ||
            ( keyStoreFile = keyStoreFile.trim() ).length() <= 0 ) {
            return ;
        }
        this.keyStoreFile = keyStoreFile;
    }

    /**
     * キーストアパスワード を取得.
     * <BR><BR>
     * @return キーストアパスワード が返されます.
     */
    public String getKeyStorePasswd() {
        return keyStorePasswd;
    }

    /**
     * キーストアパスワード を設定.
     * <BR><BR>
     * @param keyStorePasswd キーストアパスワード を設定します.
     */
    public void setKeyStorePasswd(String keyStorePasswd) {
        this.keyStorePasswd = keyStorePasswd;
    }

    /**
     * トラストストアパスワード を取得.
     * <BR><BR>
     * @return トラストストアパスワード が返されます.
     */
    public String getTrustPassword() {
        return trustPassword;
    }

    /**
     * トラストストアパスワード を設定.
     * <BR><BR>
     * @param trustPassword トラストストアパスワード を設定します.
     */
    public void setTrustPassword(String trustPassword) {
        this.trustPassword = trustPassword;
    }

    /**
     * 乱数アルゴリズム(PRNG) を取得.
     * <BR><BR>
     * @return 乱数アルゴリズム(PRNG) が返されます.
     */
    public String getRandomAlgorithm() {
        return randomAlgorithm;
    }

    /**
     * 乱数アルゴリズム(PRNG) を設定.
     * <BR><BR>
     * @param randomAlgorithm 乱数アルゴリズム(PRNG) を設定します.
     */
    public void setRandomAlgorithm(String randomAlgorithm) {
        if( randomAlgorithm == null ||
            ( randomAlgorithm = randomAlgorithm.trim() ).length() <= 0 ) {
            return ;
        }
        this.randomAlgorithm = randomAlgorithm;
    }

    /**
     * SSLプロトコル を取得.
     * <BR><BR>
     * @return SSLプロトコル が返されます.
     */
    public String getSslProtocol() {
        return sslProtocol;
    }

    /**
     * SSLプロトコル を設定.
     * <BR><BR>
     * @param sslProtocol SSLプロトコル を設定します.
     */
    public void setSslProtocol(String sslProtocol) {
        if( sslProtocol == null ||
            ( sslProtocol = sslProtocol.trim() ).length() <= 0 ) {
            return ;
        }
        this.sslProtocol = sslProtocol;
    }

    /**
     * トラストストアキーファイル名 を取得.
     * <BR><BR>
     * @return トラストストアファイル名 が返されます.
     */
    public String getTrustFile() {
        return trustFile;
    }

    /**
     * トラストストアキーファイル名 を設定.
     * <BR><BR>
     * @param trustFile トラストストアファイル名 を設定します.
     */
    public void setTrustFile(String trustFile) {
        if( trustFile == null ||
            ( trustFile = trustFile.trim() ).length() <= 0 ) {
            return ;
        }
        this.trustFile = trustFile;
    }

    /**
     * クライアント認証を設定.
     * <BR><BR>
     * @param clientAuth クライアント認証を設定します.
     */
    public void setClientAuth( boolean clientAuth ) {
        this.clientAuth = clientAuth ;
    }

    /**
     * クライアント認証を取得.
     * <BR><BR>
     * @return boolean クライアント認証が返されます.
     */
    public boolean isClientAuth() {
        return this.clientAuth ;
    }

    /**
     * SSLポート番号を設定.
     * <BR><BR>
     * @param sslPort SSLポート番号を設定します.
     */
    public void setSslPort( int sslPort ) {
        this.sslPort = sslPort ;
    }

    /**
     * SSLポート番号を取得.
     * <BR><BR>
     * @return int SSLポート番号を取得します.
     */
    public int getSslPort() {
        return this.sslPort ;
    }

    /**
     * SSLアドレスを設定.
     * <BR><BR>
     * @param sslAddress SSLアドレスを設定します.
     */
    public void setSslAddress( InetAddress sslAddress ) {
        this.sslAddress = sslAddress ;
    }

    /**
     * SSLアドレスを取得.
     * <BR>
     * @return InetAddress SSLアドレスが返されます.
     */
    public InetAddress getSslAddress() {
        return this.sslAddress ;
    }

    /**
     * 文字列に変換.
     * <BR>
     * @return String 文字列が返されます.
     */
    public String toString() {
        StringBuilder buf = new StringBuilder() ;
        buf.append( " sslProtocol:" + sslProtocol ) ;
        buf.append( " sslPort:" + sslPort ) ;
        buf.append( " sslAddress:" + sslAddress ) ;
        buf.append( " clientAuth:" + clientAuth ) ;
        buf.append( " randomAlgorithm:" + sslProtocol ) ;
        buf.append( " keyStore:" + keyStore ) ;
        buf.append( " keyManagerAlgorithm:" + keyManagerAlgorithm ) ;
        buf.append( " keyStoreFile:" + keyStoreFile ) ;
        if( trustStore != null ) {
            buf.append( " trustStore:" + trustStore ) ;
            buf.append( " trustKeyManagerAlgorithm:" + trustKeyManagerAlgorithm ) ;
            buf.append( " trustFile:" + trustStore ) ;
        }
        return buf.toString() ;
    }
}

