package jp.co.sint.mpi;

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.net.URLEncoder;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;


/**
 * <p>各種ユーティリティメソッドの実装クラス
 * Singleton パターンにより実装する.</p>
 *
 * @author SBI VeriTrans Co., Ltd.
 * @version 1.0, 2005/05 created.
 */
public final class Util {
  // 唯一のインスタンス クラスロード時にインスタンスを作成
  private static Util instance = new Util();

  // デフォルトコンストラクタ
  private Util() {}


  /**
   *  <p>インスタンスを取得する.</p>
   *
   *  @return 自分自身のインスタンス
   */
  public static Util getInstance() {
    return instance;
  }


  /**
   *   <p>GET/POST されたパラメータを取得</p>
   *
   *  @param request サーブレットリクエスト
   *  @param encode パラメータのCharset(Shift_JIS,EUC-JP,ISO2022-JP...)
   *  @return パラメータが入っているハッシュテーブル
   */
  public Hashtable getQuery(HttpServletRequest request, String encode) {
    Hashtable params = new Hashtable();
    Enumeration e = request.getParameterNames();
    while (e.hasMoreElements()) {
      String key = (String)e.nextElement();
      String[] values = request.getParameterValues(key);
      params.put(key, jp2unicode(values[0], encode));
    }
    return params;
  }

  /**
   *  <p>文字列をUnicodeに変更</p>
   *
   *  @param origin 変更対象文字列
   *  @param encode 変更対象文字列のCharset(Shift_JIS,EUC-JP,ISO2022-JP...)
   *  @return パラメータが入っているハッシュテーブル
   */
  private String jp2unicode(String origin, String encode) {
    try {
      if (origin == null) {
        return null;
      }
      return new String(origin.getBytes("8859_1"), encode);
    }
    catch (UnsupportedEncodingException e) {
      return origin;
    }
  }

  /**
   * <p>決済情報ハッシュテーブルをエンコーディング</p>
   * <p>エンコードルール： 
   * <br>キーとバリューを連結：key1=value1&key2=value2...</br>
   * <br>連結された文字列に対して標準エンコードを行う</br>
   * </p>
   *
   *  @param params 決済情報ハッシュテーブル
   *  @return エンコーディング文字列
   */
  public String urlEncode(Hashtable params) throws Exception {
    StringBuffer buf = new StringBuffer();
    Enumeration e = params.keys();
    while (e.hasMoreElements()) {
      if (buf.length() > 0) buf.append("&");
      String key = (String)e.nextElement();
      buf.append(key);
      buf.append("=");
      buf.append(URLEncoder.encode((String)params.get(key), "UTF-8"));
    }
    return buf.toString();
  }

  /**
   * <p>決済情報エンコード文字列をデコーディング</p>
   * <p>デコードルール： 
   * <br>連結文字列に対して標準デコードを行う</br>
   * <br>デコード結果(key1=value1&key2=value2...)からハッシュに戻る</br>
   *  </p>
   *
   *  @param s 決済情報エンコード文字列
   *  @return デコーディングされたハッシュテーブル
   */
  public Hashtable urlDecode(String s)  throws Exception {
    Hashtable tokens = new Hashtable();
    StringTokenizer st = new StringTokenizer(s, "&");
    String key = "";
    while (st.hasMoreTokens()) {
      try {
        String keyValue = st.nextToken();
        StringTokenizer st2 = new StringTokenizer(keyValue, "=");
        key = st2.nextToken();
        String value = URLDecoder.decode(st2.nextToken(), "UTF-8");
        if (value == null) {
          value = "";
        }
        //String value = URLDecoder.decode(st2.nextToken(), "UTF-8");
        tokens.put(key, value);
      }
      catch (NoSuchElementException ae){
        tokens.put(key, "");
      }
    }
    return tokens;
  }

  /**
   *  <p>文字列から数字以外を除去</p>
   *
   *  @param s 対象文字列
   *  @return 除去後の文字列
   */
  public static String stripCardNumber(String s) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0 ; i < s.length() ; i++) {
      char c = s.charAt(i);
      if (Character.isDigit(c)) sb.append(c);
    }
    return sb.toString();
  }
}