/*
 * IRCAddress.java
 * IRCCore
 *
 * Created by tarchan on Aug 07, 2006.
 * Copyright (c) 2006 tarchan. All rights reserved.
 */
package com.mac.tarchan.irc;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;

/**
 * IRCAddress
 * 
 * @author tarchan
 * @author nori090
 */
public class IRCAddress {
    /** debug logger */
    private static final Logger log = Logger.getLogger( IRCAddress.class );

    /** system property key */
    private static final String protocolPathProp = "java.protocol.handler.pkgs";

    /** URL */
    private URL url;

    /** アドレス */
    private String host;

    /** ポート */
    private int port;

    /** チャンネル名 */
    private String channel;

    /** ユーザ名 */
    private String user;

    /** パスワード */
    private String password;

    /** ニックネーム */
    private String nick;

    /** 名前 */
    private String real;

    /** モード */
    private int mode;

    static {
        // URCコネクションハンドラに com.mac.tarchan.irc.Hnadler を設定
        String v = System.getProperty( protocolPathProp, "" );
        if ( v != "" ) {
            v += "l";
        }
        v += "com.mac.tarchan";
        System.setProperty( protocolPathProp, v );
    }

    public IRCAddress( String spec ) {
        this.setURL( spec );
    }

    /**
     * URL を設定します。
     * 
     * <pre>
     * [irc://][&lt;user&gt;[':'&lt;pass&gt;]]&lt;host&gt;[:&lt;port&gt;]['/'&lt;path&gt;['#'&lt;channel&gt;]]
     * </pre>
     * 
     * @param spec URL
     */
    public void setURL( String spec ) {
        // IRCアドレス
        // IRCプロキシ
        // チャンネル名
        try {
            assert spec == null : "url string is null";
            if ( !spec.startsWith( "irc://" ) )
                spec = new StringBuffer( spec ).insert( 0, "irc://" ).toString();
            url = new URL( spec );
        }
        catch ( MalformedURLException x ) {
            log.error( x );
            throw new RuntimeException( x );
        }

        host = url.getHost();
        port = url.getPort();
        String ref = url.getRef();
        if ( ref.length() > 0 ) {
            channel = "#" + ref;
        }
        String[] userinfo = url.getUserInfo().split( ":", 2 );
        if ( userinfo.length >= 2 ) {
            nick = real = user = userinfo[0];
            password = userinfo[1];
        }
    }

    /**
     * URL を返します。
     * 
     * @return URL
     */
    public URL toURL() {
        return url;
    }

    public URL getUrl() {
        return url;
    }

    public IRCConnection openConnection() {
        try {
            URLConnection connection = url.openConnection();
            connection.setRequestProperty( "nick", getNick() );
            return (IRCConnection) connection;
        }
        catch ( IOException x ) {
            x.printStackTrace();
            return null;
        }
    }

    /**
     * 指定した値が空かどうかを判定します。
     * 
     * @param value 値
     * @return 空の場合は true、そうでない場合は false
     */
    private boolean isEmpty( String value ) {
        return value == null || value.trim().length() == 0;
    }

    /**
     * アドレスを返します。
     * 
     * @return アドレス
     */
    public String getHost() {
        return host;
    }

    /**
     * ポートを返します。
     * 
     * @return ポート
     */
    public int getPort() {
        return port;
    }

    /**
     * パスワードを返します。
     * 
     * @return パスワード
     */
    public String getPassword() {
        return password;
    }

    public void setPassword( String pass ) {
        if ( isEmpty( this.password ) )
            this.password = pass;
    }

    /**
     * ユーザ名を返します。
     * 
     * @return ユーザ名
     */
    public String getUser() {
        return user;
    }

    public void setUser( String user ) {
        if ( isEmpty( this.user ) )
            this.user = user;
    }

    /**
     * ニックネームを返します。
     * 
     * @return ニックネーム
     */
    public String getNick() {
        return nick;
    }

    /**
     * ニックネームを設定します。
     * 
     * @param nick ニックネーム
     */
    public void setNick( String nick ) {
        this.nick = nick;
    }

    /**
     * 名前を返します。
     * 
     * @return 名前
     */
    public String getReal() {
        return real;
    }

    public void setReal( String real ) {
        this.real = real;
    }

    /**
     * モードを返します。
     * 
     * @return モード
     */
    public int getMode() {
        return mode;
    }

    public void setMode( int mode ) {
        this.mode = mode;
    }

    /**
     * チャンネル名を返します。
     * 
     * @return チャンネル名
     */
    public String getChannel() {
        return channel;
    }

    public void setChannel( String channel ) {
        this.channel = channel;
    }

    /**
     * 文字列表現を返します。
     */
    public String toString() {
        return new ToStringBuilder( this ).append( "url", url ).append( "host", host ).append( "port", port ).append(
                                                                                                                      "channel",
                                                                                                                      channel ).append(
                                                                                                                                        "user",
                                                                                                                                        user ).append(
                                                                                                                                                       "password",
                                                                                                                                                       password ).append(
                                                                                                                                                                          "nick",
                                                                                                                                                                          nick ).append(
                                                                                                                                                                                         "real",
                                                                                                                                                                                         real ).append(
                                                                                                                                                                                                        "mode",
                                                                                                                                                                                                        mode ).toString();
    }

}
