package org.maachang.util.net;

import java.util.List;

import org.maachang.util.StringUtil;

/**
 * ネットワークアドレス取得WindowsNT版. <BR>
 * <BR>
 * WindowsNT版のネットワークアドレス取得処理です.
 * 
 * @version 2008/10/28
 * @author masahito suzuki
 * @since MaachangBase 1.08
 */
class NetAdapterByWinNT extends AbstractNetAdapter {

    /**
     * IPアドレス取得コマンド.
     */
    private static final String IPCONFIG_COMMAND = "ipconfig /all";

    /**
     * 媒体開始文字.
     */
    private static final String ADAPTER_NAME = "ethernet adapter";

    /**
     * 区切り値.
     */
    private static final String DIV_CODE = ":";

    /**
     * 詳細名.
     */
    private static final String ETC_NAME = "description";

    /**
     * IPアドレス.
     */
    private static final String IP_ADDR_1 = "ip";

    private static final String IP_ADDR_2 = "address";

    /**
     * サブネットマスク.
     */
    private static final String SUB_NET_1 = "subnet";

    private static final String SUB_NET_2 = "mask";

    /**
     * macアドレス.
     */
    private static final String MAC_ADDR_1 = "physical";

    private static final String MAC_ADDR_2 = "address";

    /**
     * MACアドレス区切り修正元.
     */
    private static final String MAC_ADDR_SRC = "-";

    /**
     * MACアドレス区切り修正先.
     */
    private static final String MAC_ADDR_DEST = ":";

    /**
     * コンストラクタ.
     */
    public NetAdapterByWinNT() {
        init();
    }

    /**
     * ネットワーク情報取得処理.
     * 
     * @exception Exception
     *                例外.
     */
    public void load() throws Exception {
        int i;
        int len;
        int localCheck;

        List<String> cmdOut = null;
        String name = null;
        String value = null;

        try {

            this.clear();
            cmdOut = super.runExec(NetAdapterByWinNT.IPCONFIG_COMMAND);

            len = cmdOut.size();
            for (i = 0, localCheck = 0; i < len; i++) {

                String bcmd = cmdOut.get(i) ;
                String cmd = bcmd.toLowerCase() ;

                // adapter名を調べる.
                if (cmd.indexOf(NetAdapterByWinNT.ADAPTER_NAME) != -1
                        && cmd.indexOf(NetAdapterByWinNT.DIV_CODE) == cmd
                                .length() - 1) {
                    int p = cmd.indexOf(NetAdapterByWinNT.ADAPTER_NAME) ;
                    name = StringUtil.trim( bcmd.substring( p+NetAdapterByWinNT.ADAPTER_NAME.length(),cmd.length()-1 ) ) ;
                }
                // 詳細名の場合.
                else if (cmd.indexOf(NetAdapterByWinNT.ETC_NAME) != -1
                        && cmd.indexOf(NetAdapterByWinNT.DIV_CODE) != -1) {
                    // 何もしない.
                    continue;
                }
                // IPアドレスの場合.
                else if (cmd.indexOf(NetAdapterByWinNT.IP_ADDR_1) != -1
                        && cmd.indexOf(NetAdapterByWinNT.IP_ADDR_2) != -1
                        && cmd.indexOf(NetAdapterByWinNT.DIV_CODE) != -1) {
                    value = StringUtil.trim(bcmd.substring(bcmd
                            .indexOf(NetAdapterByWinNT.DIV_CODE) + 1));

                    // 対象IPアドレスがローカルアドレスを示す場合.
                    if (value.equals(LOCAL_IP) == true) {
                        localCheck++;
                    }
                    super.setIpAddress(name, value);
                }
                // サブネットマスクの場合.
                else if (cmd.indexOf(NetAdapterByWinNT.SUB_NET_1) != -1
                        && cmd.indexOf(NetAdapterByWinNT.SUB_NET_2) != -1
                        && cmd.indexOf(NetAdapterByWinNT.DIV_CODE) != -1) {
                    value = StringUtil.trim(bcmd.substring(bcmd
                            .indexOf(NetAdapterByWinNT.DIV_CODE) + 1));
                    super.setSubnetMask(name, value);
                }
                // MACアドレスの場合.
                else if (cmd.indexOf(NetAdapterByWinNT.MAC_ADDR_1) != -1
                        && cmd.indexOf(NetAdapterByWinNT.MAC_ADDR_2) != -1
                        && cmd.indexOf(NetAdapterByWinNT.DIV_CODE) != -1) {
                    value = StringUtil.trim(bcmd.substring(bcmd
                            .indexOf(NetAdapterByWinNT.DIV_CODE) + 1));
                    value = StringUtil.changeString(value,
                            NetAdapterByWinNT.MAC_ADDR_SRC,
                            NetAdapterByWinNT.MAC_ADDR_DEST).toUpperCase();
                    super.setMacAddress(name, value);
                }
                // その他.
                else {
                    // 何もしない.
                    continue;
                }

            }

            // ローカルアドレスが存在しない場合.
            if (localCheck == 0) {

                // アドレスを追加.
                super.setIpAddress(AbstractNetAdapter.DEFAULT_ETHER_NAME, LOCAL_IP);
                // ホスト名を追加.
                super.setSubnetMask(AbstractNetAdapter.DEFAULT_ETHER_NAME,
                        AbstractNetAdapter.LO_HOST_SUB);

            }
        } catch (Exception e) {
            this.clear();
            throw e;
        } finally {
            cmdOut = null;
            name = null;
            value = null;
        }

    }

}
