package jp.co.sint.mpi;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import java.util.Hashtable;
import java.io.IOException;
import java.util.Map;
//import java.util.Date;
//import java.text.SimpleDateFormat;

import java.util.Iterator;

import jp.co.sint.config.SIConfig;

import org.apache.log4j.Logger;

/**
 * <p>認証結果検証機能のダミークラス
 * リクエストからＭＤを解析し、MDKに結果の検証を依頼する.</p>
 * @author SBI VeriTrans Co., Ltd.
 * @version 1.0, 2005/05 created.
 */
public class McValidController extends McController {
    protected Logger logger = null;
    /**
    *  <p>POST リクエストを処理するメソッド</p>
    *  @param request HttpServletRequest HTTPサーブレットリクエスト
    *  @param response HttpServletResponse HTTPサーブレットレスポンス
    */
    public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
        String orderID = null;
        String cardExp = null;
        String amount = null;
        String cardNumber = null;
        String  sAction = null;
        String txnID = null;
        String paRes = null;
        String msg = null;
        String merchant_no = null;
        
        logger = LoggerFactory.getTraceLogger();
        logger.info("******************* VERIFY has begun *******************");
        
        try {
            Hashtable params = Util.getInstance().getQuery(request, getEncode());
            // ログ
            Iterator itr = params.keySet().iterator();
            logger.info("***** VERIFIED Data from ACS *****");
            while (itr.hasNext()) {
                String key = (String)itr.next();
                String value = (String)params.get(key);
                logger.info("key["+ key +"]=[" + value + "]");
            }
            
            // カードホルダから POST されてくる PARes およびMDを取得
            paRes = (String)params.get(PARES);
            final String md = (String)params.get(MD);
            
            logger.debug(PARES + "=[" + paRes + "]");
            logger.debug(MD + "=[" + md + "]");
            
            // MDKにMD解析
            //System.setProperty("Jp.BuySmart.DddLib.directPath", "true");
            Jp.BuySmart.DddLib.Transaction dddtran = Jp.BuySmart.DddLib.TransactionFactory.createInstance();
            
            Map MdParams = new Hashtable();
            MdParams = dddtran.analyzeMerchantData(md);
            
            //debug
            /*
            logger.info("****** Analyzed MD from MDK *******");
            itr = MdParams.keySet().iterator();
            while (itr.hasNext()) {
                String key = (String)itr.next();
                String value = (String)MdParams.get(key);
                //logger.info("key["+ key +"]=[" + value + "]");
            }
            */
            // jspTemplate取得
            //final String jspTemplate = getJspTemplate();
            // トランザクション番号の取得
            txnID = (String)MdParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_A_TXN_ID);
            // MDから金額取得
            amount = (String)MdParams.get(Jp.BuySmart.DddLib.Transaction.REQ_TAG_A_AMOUNT);
            // MDからテストマーチャント指定番号取得
            merchant_no = (String)MdParams.get("merchant_specify");
            // MDからお客様設定用項目取得(McAuthServletで値を設定した場合にご使用下さい)
            //String customizeKey = (String)MdParams.get("customize-key");
            
            // 送信電文格納マップ定義
            Map sendParams = new Hashtable();
            
            // 初期値設定
            sendParams = Jp.BuySmart.DddLib.TransactionFactory.createRequest();
            // 送信電文格納マップにコマンド文字列追加
            sendParams.put(Jp.BuySmart.DddLib.Transaction.REQ_COMMAND, Jp.BuySmart.DddLib.Transaction.CMD_VERIFY);
            // 送信電文格納マップにトランザクション番号追加
            sendParams.put(Jp.BuySmart.DddLib.Transaction.REQ_TAG_Q_TXN_ID, txnID);
            // 送信電文格納マップにPARes-MSG追加
            if (paRes == null) {
                paRes = "";
            }
            sendParams.put(Jp.BuySmart.DddLib.Transaction.REQ_TAG_V_PARES, paRes);
            
            // ログ
            logger.info("********** BEFORE VERIFIEY Data SEND to MDK ***********");
            itr = sendParams.keySet().iterator();
            while (itr.hasNext()) {
                String key = (String)itr.next();
                String value = (String)sendParams.get(key);
                logger.info("key["+ key +"]=[" + value + "]");
            }
            
            // 本人認証結果検証の依頼
            Map receiveParams = new Hashtable();
            receiveParams = dddtran.doTransaction(sendParams);
            
            // ログ
            logger.info("**********  AFTER VERIFIED Data from MDK ***********");
            int psize = receiveParams.size();
            logger.info("size of verified datamap:[" + receiveParams.size() +"]");
            
            if (psize >0) {
                itr = receiveParams.keySet().iterator();
                while (itr.hasNext()) {
                    String key = (String)itr.next();
                    String value = (String)receiveParams.get(key);
                    logger.info("key["+ key +"]=[" + value + "]");
                }
            }
            else {
                final String message = "*** 本人認証結果検証失敗　検証結果データ戻らず ***";
                logger.info(message);
                request.setAttribute("errmsg", message);
                dispatchTo("/casher?a="+SIConfig.SIACTION_CANCEL, request, response);
                return;
            }
            // action-code取得
            sAction = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_ACTION_CODE);
            logger.info("action-code = " + sAction);
            // PARes からパラメータを抽出
            final String xMsgVersion = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_MSG_VERSION);
            logger.info("Msg-Version-Number = " + xMsgVersion);
            final String xID = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_XID);
            logger.info("XID = " + xID);
            final String xStatus = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_XSTATUS);
            logger.info("XStatus = " + xStatus);
            final String xCavv = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_CAVV);
            logger.info("CAVV = " + xCavv);
            final String xCavvAlgorithm = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_CAVV_ALGORITHM);
            logger.info("CAVV-Algorithm = " + xCavvAlgorithm);
            final String xEci = (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_V_3D_ECI);
            logger.info("ECI = " + xEci);
            
            // action-codeにより処理を決定
            // 本人認証結果が決済可の場合
            if ((sAction.equals(SETTLEMENT_PERMITION)) || (sAction.equals(SETTLEMENT_PERMITION_AUTH_MISS))) {
                // 取引結果ページ表示
                request.setAttribute("result", receiveParams);
                dispatchTo("/thanks?a="+SIConfig.SIACTION_REGIST, request, response);//受注確定
                return;
            }
            // 本人認証結果が決済不可の場合
            else if (sAction.equals(SETTLEMENT_REFUSED)) {
                request.setAttribute("result", receiveParams);
                msg = "エラーコード[" + (String)receiveParams.get(Jp.BuySmart.DddLib.Transaction.RES_TAG_ERR_CODE) + "] 本人認証に失敗しました。決済不可です。";
                request.setAttribute("errmsg",    msg);
                dispatchTo("/casher?a="+SIConfig.SIACTION_CANCEL, request, response);
                // セッションを破棄する
                //session.invalidate();
                return;
            }
            else if (sAction == null){
                request.setAttribute("result", receiveParams);
                request.setAttribute("errmsg", "アクションコードがNULLです。");
                dispatchTo("/casher?a="+SIConfig.SIACTION_CANCEL, request, response);
                return;
            }
        }
        catch (Exception e) {
            logger.info("exception 発生:", e);
            // エラーページを表示する
            dispatchToError(e, request, response);
        }
    }
}
