package com.yijia.zthandpos.pos.test;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;

import com.szzt.sdk.device.Constants;
import com.szzt.sdk.device.card.ContactlessCardReader;
import com.szzt.sdk.device.card.SmartCardReader;
import com.szzt.sdk.device.emv.EMV_STATUS;
import com.szzt.sdk.device.emv.EmvInterface;
import com.szzt.sdk.device.pinpad.PinPad;
import com.szzt.sdk.device.pinpad.PinPad.OnSendKeyListerner;
import com.yijia.zthandpos.pos.BaseActivity;
import com.yijia.zthandpos.pos.R;
import com.yijia.zthandpos.pos.utils.HexDump;
import com.yijia.zthandpos.pos.utils.MessageManager;
import com.yijia.zthandpos.pos.utils.Shower;
import com.yijia.zthandpos.pos.utils.StringUtil;
import com.yijia.zthandpos.pos.utils.StringUtility;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class EMVActivity extends BaseActivity {
	private static final int MSG_WAIT_FOR_CARD = 0;
	private MessageManager messageManager;
    private EmvInterface emvInterface;
    private PinPad pinPad;
    private Button  mClearButton;
    private Button  mEmvStart;
    private Button  mEmvClose;
    private Button  mEmvElectronic;
    private Button  mElectronicCashInquiry;
    private Button  mEmvSetParam;
    private HandlerThread            mWaitForCardHandlerThread;
    volatile boolean         mIsWaitingForCard = false;
    volatile boolean         mHasCard          = false;
    private MyHandler        myHandler;
    private static ArrayList<byte[]> mAIDParams;
    private static ArrayList<byte[]> mCAPKParams;

    private static ArrayList<String> mAIDParamInString;
    private static ArrayList<String> mCAPKParamInString;
    
    private static String  mTermInfo;
    private Shower shower ;
    private byte mTransType=EmvInterface.TRANS_GOODS_SERVICE;
    private static final int EMV_WAIT_CARD = 113;
    private static final int EMV_ELECTRO_CASH_WAIT_CARD = 114;
    private static final int EMV_ELECT_TRANS_WAIT_CARD = 115;
    private class MyHandler extends Handler {
        public MyHandler(Looper looper) {
            super(looper);
        }
        public void handleMessage(Message m) {
            int what = m.what;
            if(what == EmvInterface.EMV_PROCESS_MSG){
                int status = m.arg1;
                int retcode = m.arg2;
                EmvTest(status,retcode);
            }else if(what == EmvInterface.EMV_CARD_MSG){
                int removed = m.arg1;
                if(removed == EmvInterface.CARD_REMOVED){
                    
                }
            }else if (what == MSG_WAIT_FOR_CARD) {
            }else if (what == EMV_WAIT_CARD) {
				messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_wait_card),
	                     Color.GREEN);
			}else if(what == EMV_ELECTRO_CASH_WAIT_CARD)
			{
				messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_get_electro_cash),
	                     Color.GREEN);
			}else if(what == EMV_ELECT_TRANS_WAIT_CARD)
			{
				messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_elect_trans_wait_card),
	                     Color.GREEN);
			}
        }
    }
    private final Handler handler=new Handler(Looper.getMainLooper());
    //接触卡 isEmvInit:true 电子现金 ; false:联机交易
    private void smart_emv(boolean isEmvInit){
    	if (!mIsWaitingForCard) {
            mIsWaitingForCard = true;
            int result = smartCardReader.waitForCard(0, Constants.WAIT_INFINITE);
	          if (result < 0) {
	        	  messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_card_contact)+shower.getString(R.string.msg_card_read_error));
	          } else {
	        	  contactlessCardReader.close();
	        	  messageManager.AppendInfoMessageInUiThread("Contact card");
	        	  byte[] data=new byte[256];
	        	  int ret=smartCardReader.powerOn(0, data);
	        	  if(ret>0){
	        		  if(!isEmvInit)
	        		  {
	        			  smart();
	        		  }else{
	        			  EmvInit(data, EmvInterface.READER_TYPE_CONTACT_CARD);
	        		  }
	        	  }
	              	
	          }
	          mIsWaitingForCard = false;
        }
    }
    
    private void smart(){
    	emvInterface.setForceOnline(1);
		emvInterface.initialize(myHandler);
	    byte[] term = HexDump.hexStringToByteArray("9F660436800080");
		emvInterface.setTerminalParam(term);
		emvInterface.preprocess(1);
		emvInterface.setCardType( EmvInterface.READER_TYPE_CONTACT_CARD);
        emvInterface.setTransAmount(1);		             
        emvInterface.setTransType(EmvInterface.TRANS_GOODS_SERVICE);        
        emvInterface.process();
    }
    private void EmvInit(byte[] atr,int result) {
    	emvInterface.initialize(myHandler);
    	emvInterface.preprocess(0);
    	emvInterface.setTransAmount(1);
    	emvInterface.setCardType(result);
        emvInterface.setTransType(mTransType);        
        emvInterface.process();		
	}
    //非接卡 isEmvInit：false电子现金 ；true:联机交易
    volatile boolean mIsWaitingForCard2 = false;
    private void contact_emv(boolean isEmvInit){
    	if (!mIsWaitingForCard2) {
    		mIsWaitingForCard2 = true;
            int result = contactlessCardReader.waitForCard(Constants.WAIT_INFINITE);
	          if (result < 0) {
	        	  messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_card_contactless)+shower.getString(R.string.msg_card_read_error));

	          } else {
	        	  smartCardReader.close();
	        	  handler.post(new Runnable() {
						@Override
						public void run() {
							 messageManager.AppendInfoMessage("Contactless card");
						}
					});
	        	  byte[] data=new byte[256];
	        	  int ret=contactlessCardReader.powerOn( data);
	        	  if(ret>0){
	        		  if(!isEmvInit)
	        		  {
		        		  emvInterface.setForceOnline(1);
		        		  emvInterface.initialize(myHandler);
		        		  byte[] term = HexDump.hexStringToByteArray("9F660436800080");
		  				  emvInterface.setTerminalParam(term);
		        		  emvInterface.preprocess(1);
		        		  emvInterface.setCardType( EmvInterface.READER_TYPE_CONTACTLESS_CARD);
			              emvInterface.setTransAmount(1);		              
			              emvInterface.setTransType(EmvInterface.TRANS_GOODS_SERVICE);        
			              emvInterface.process();	  
	        		  }else{
	        			  EmvInit(data, EmvInterface.READER_TYPE_CONTACTLESS_CARD);
	        		  }
	        	  }
	          }
	          mIsWaitingForCard2 = false;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        setContentView(R.layout.activity_emv);
        shower = new Shower(this);
        boolean isConnected = mainApplication.isDeviceManagerConnetcted();
        init(isConnected);
        loadEmvParam();
    }
    
    @Override
    public void onResume() {
        messageManager.AppendInfoMessage(shower.getString(R.string.test_emv));
        if (mWaitForCardHandlerThread == null) {
            mWaitForCardHandlerThread = new HandlerThread("wait_for_card");
        }
        mWaitForCardHandlerThread.start();
        myHandler = new MyHandler(mWaitForCardHandlerThread.getLooper());
        super.onResume();
    }
    
    @Override
    public void onDestroy() {
        emvInterface.processExit();
        myHandler.removeMessages(MSG_WAIT_FOR_CARD);
        myHandler.getLooper().quit();
        myHandler = null;
        mWaitForCardHandlerThread = null;
        mIsWaitingForCard = false;
        mIsWaitingForCard2 = false ;
        pinPad.close();
        super.onDestroy();
    }

    private SmartCardReader smartCardReader = null ;
    private ContactlessCardReader contactlessCardReader = null ;
    private void init(boolean isConnected) {
        if (messageManager == null) {
            TextView text = (TextView) findViewById(R.id.emv_text);
            text.setMovementMethod(ScrollingMovementMethod.getInstance());
            messageManager = new MessageManager(this, text);
            mClearButton = (Button) findViewById(R.id.emv_clear);
            mClearButton.setOnClickListener(listener);
            mEmvStart = (Button) findViewById(R.id.emv_start);
            mEmvStart.setOnClickListener(listener);
            mEmvClose = (Button) findViewById(R.id.emv_stop);
            mEmvClose.setOnClickListener(listener);
            mEmvElectronic = (Button) findViewById(R.id.emv_electronic_cash);
            mEmvElectronic.setOnClickListener(listener);
            mElectronicCashInquiry = (Button) findViewById(R.id.emv_electronic_cash_inquiry);
            mElectronicCashInquiry.setOnClickListener(listener);
            mEmvSetParam = (Button) findViewById(R.id.emv_set_param);
            mEmvSetParam.setOnClickListener(listener);
            emvInterface = mainApplication.getEmvInterface();
            smartCardReader = mainApplication.getSmartCardReader();
            contactlessCardReader = mainApplication.getContactlessCardReader();
            pinPad = mainApplication.getPinPad();
        }
        mClearButton.setEnabled(isConnected);
        mEmvStart.setEnabled(isConnected);
        mEmvClose.setEnabled(isConnected);
    }

    private final OnClickListener listener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.emv_clear:
                messageManager.clear();
                break;
            //联机交易
            case R.id.emv_start:
           	 	myHandler.sendEmptyMessage(EMV_WAIT_CARD);
           	 	mTransType=EmvInterface.TRANS_GOODS_SERVICE;
			    openCardRead(false);
            	break;
            //电子现金查询
            case R.id.emv_electronic_cash_inquiry:
            	myHandler.sendEmptyMessage(EMV_ELECTRO_CASH_WAIT_CARD);
            	mTransType = (byte) 0xF4;
            	openCardRead(true);
            	break;
            //电子现金交易
            case R.id.emv_electronic_cash:
            	myHandler.sendEmptyMessage(EMV_ELECT_TRANS_WAIT_CARD);
            	mTransType=EmvInterface.TRANS_GOODS_SERVICE;
            	openCardRead(true);
            	break;
            //设置参数
            case R.id.emv_set_param:
            	emvSetParam();
            	break;
            //停止测试
            case R.id.emv_stop:
            	closeReader();
            	break;
            default:
                break;
            }
        }
    };
    
    //非接卡、接触卡
    private void openCardRead(final boolean isEmvInit){
    	 int res = smartCardReader.open(0, new SmartCardReader.SCReaderListener() {
				
				@Override
				public void notify(int nSlotIndex, int nEvent) {
					
				}
			});
		    if(res>=0){
		    	new Thread(){
		    		public void run(){
		    			smart_emv(isEmvInit);
		    		}
		    	}.start();
		    }
     	
     	int res2 = contactlessCardReader.open();
		    if(res2>=0){
		    	new Thread(){
		    		public void run(){
		    			contact_emv(isEmvInit);
		    		}
		    	}.start();
		 }
    }
    
    //设置参数
    private void emvSetParam(){
    	new Thread(new Runnable() {
			
			@Override
			public void run() {
				loadEmvParam();
				setEmvParam();
			}
		}).start();
    }
    private void loadEmvParam(){
        if(mAIDParams == null){
            mAIDParams = new ArrayList<byte[]>();
            mCAPKParams = new ArrayList<byte[]>();
            mAIDParamInString = new ArrayList<String>();
            mCAPKParamInString = new ArrayList<String>();
        }
        if(mAIDParams.size() != 0 || mCAPKParams.size() != 0){
            return;
        }
        try {
            InputStreamReader inputReader = new InputStreamReader(
                    getResources().openRawResource(R.raw.params));
            BufferedReader bufferedReader = new BufferedReader(inputReader);
            ArrayList<byte[]> activeList = null;
            ArrayList<String> stringList = null;
            while(true){
                String line = bufferedReader.readLine();
                if(line == null)
                    break;
                if(line.startsWith("AID=")){
                    activeList = mAIDParams;
                    stringList = mAIDParamInString;
                    continue;
                }else if(line.startsWith("CAPK=")){
                    activeList = mCAPKParams;
                    stringList = mCAPKParamInString;
                    continue;
                }else if(line.startsWith("TERM=")){
                    line = bufferedReader.readLine();
                    mTermInfo = line;
                    continue;
                }
                stringList.add(line);
                byte[] data = StringUtil.hexString2bytes(line);
                activeList.add(data);
            }
            bufferedReader.close();
            inputReader.close();
        } catch (Exception e) {
            messageManager.AppendInfoMessageInUiThread(
                    shower.getString(R.string.msg_emv_load_para_error) + e.getMessage());
        }
    }
    
    private void setEmvParam() {
        int index = 0;
        for(byte[] param:mAIDParams){
            int nret = emvInterface.updateAidParam(1, param);
            messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_aid) + (index)
                    +"]=" + mAIDParamInString.get(index++) + " = " + nret);
        }
        index = 0;
        for(byte[] param:mCAPKParams){
            int nret = emvInterface.updateCAPKParam(1, param);
            messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_capk) + (index)
                    +"]=" + mCAPKParamInString.get(index++) + " = " + nret);
        }
        if(mTermInfo != null){
            int nret = emvInterface.setTerminalParam(StringUtil.hexString2bytes(mTermInfo));
            messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_teminal)+nret);
        }
    }

    private void EmvTest(int status,int retcode) {
    	Log.e("EmvTest", "status:"+status+" retcode:"+retcode);
        if(status == EmvInterface.STATUS_CONTINUE){
            switch(retcode){
            //请求选择候选应用列表
            case EMV_STATUS.EMV_REQ_SEL_CANDIDATES:
            //请求再次选择候选列表
            case EMV_STATUS.EMV_REQ_SEL_CANDIDATES_AGAIN:
                byte[] candidateList = new byte[300];
                int length = emvInterface.getCardCandidateList(candidateList);
                if(length <= 0){
                    emvInterface.process();
                    return;
                }
                int nret = emvInterface.setCardCandidateListResult(10);
                messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_sum_up)+length +
                        shower.getString(R.string.msg_emv_apps) + shower.getString(R.string.msg_emv_chose_app)
                        + nret);
                emvInterface.process();
                break;
             //请求持卡人输入联机pin   
            case EMV_STATUS.EMV_REQ_ONLINE_PIN:
            	//输入联机pin
            	onlinePinPad();
            	break;
            //请求联机交易
            case EMV_STATUS.EMV_REQ_GO_ONLINE:
            	byte[] data=new byte[256];
            	byte[] recvFiled55=new byte[256];            	
            	int index=0;
            	int[] tag=new int[]{0x82,0x84,0x95,0x9F26,0x9F27,0x9F10,0x9F37,0x9F36,0x9A,0x9C,0x9F02,0x5F2A,0x9F1A,0x9F03,0x9F33,0x9F34,0x9F35,0x9F1E,0x9F09,0x9F41};
            	for(int i=0;i<tag.length;i++){
            		int len=emvInterface.getTagData(tag[i], data);
                	if(len>0){
                		Log.e("tag", tag[i]+"-->"+StringUtility.ByteArrayToString(data, len));
                		int tagIndex;
                		if(tag[i]>0xFF){
                		    Log.e("status", "status-->"+(tag[i]>>8)+"-->"+(tag[i]<<8));
                			tagIndex=recvFiled55[index++]=(byte)(tag[i]/0xff);
                		}
                		recvFiled55[index++]=(byte)(tag[i]&0xff);
                		recvFiled55[index++]=(byte) len;
                		System.arraycopy(data, 0, recvFiled55, index, len);
                		index+=len;
                	}
            	}
            	byte[] filed55=new byte[index];
            	System.arraycopy(recvFiled55, 0, filed55, 0, index);
            	emvInterface.setOnlineResult(2, filed55, filed55.length);
            	emvInterface.process();
            	break;
            //得到卡号
            case EMV_STATUS.EMV_REQ_CARD_CONFIRM:
                byte[] tagData = new byte[100];
                int tagDataLength = emvInterface.getTagData(0x57, tagData);
                cardNumber = StringUtility.getStringFormat(tagData, tagDataLength);
                messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_card_num)
                        + cardNumber);
                emvInterface.process();
                break;
            default:
            	emvInterface.process();
                break;
            }
        }
        //完成状态
        else if(status == EmvInterface.STATUS_COMPLETION){
        	messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_trade_over));
        	//电子现金余额查询
        	if ((mTransType & 0xFF) == 0xF4) {
				if (retcode == 100) {
					byte[] temp = new byte[32];
					String amount = "0.00";
					emvInterface.getICCTagData(0x9F79, temp);
					int ret = emvInterface.getTagData(0x9F79, temp);
					if (ret >= 0) {
						amount = HexDump.decBytesToHex(temp, ret);
					}
					messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_elect_cash_balance)
							+ String.format("%.2f",
									Integer.parseInt(amount) * 1.0 / 100));
				}
			}else if ((mTransType & 0xFF) == 0xF0){
				if (retcode == 100){
					byte[] sum = new byte[1];
					emvInterface.getTransLog(0x101, sum);
					System.out.println("sum:" + sum[0]);		
					byte[] fmt_dol = new byte[60];
					byte[] rec_val = new byte[256];
					for (int i=1; i<=sum[0]; i++){
						int index = 0;
						
						int len = emvInterface.getTransLog(0x102, fmt_dol);
						System.out.println("fmt_dol:" + HexDump.decBytesToHex(fmt_dol));
						
						len = emvInterface.getTransLog(i, rec_val);
						System.out.println("rec_val:" + HexDump.decBytesToHex(rec_val, len));
						
			            StringBuffer stringBuffer = new StringBuffer();

			            index = 0;
			            stringBuffer.append("9A03");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 3));
			            index += 3;
			            stringBuffer.append("9F2103");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 3));
			            index += 3;
			            stringBuffer.append("9F0206");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 6));
			            index += 6;
			            index += 6;
			            stringBuffer.append("9F1A02");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 2));
			            index += 2;
			            stringBuffer.append("5F2A02");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 2));

			            index += 2;
			            stringBuffer.append("9F4E14");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 20));
			            index += 20;
			            stringBuffer.append("9C01");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 1));
			            index += 1;
			            stringBuffer.append("9F3602");
			            stringBuffer.append(HexDump.toHexString(rec_val, index, 2));
			            
			            messageManager.AppendInfoMessageInUiThread(stringBuffer.toString());
					}
				}
			}else if ((mTransType & 0xFF) == 0xF2){
				if (retcode == 100){
					String cardSN = "0" + HexDump.decBytesToHex(getTag(0x5F34));
					System.out.println("cardSN:" + cardSN);
					String cardNO = HexDump.decBytesToHex(getTag(0x5A));
					System.out.println("cardNO:" + cardNO);
				}
			}
        	byte[] data=new byte[1024];
        	emvInterface.getTransLog(0, data);
        }else if(status == EmvInterface.STATUS_ERROR){
        	messageManager.AppendInfoMessageInUiThread("Ic error");
        }
    }
    //获取交易日志
    private byte[] getTag(int tagInt){
        byte[] temp = new byte[256];
        byte[] result = null;
        int ret = emvInterface.getTagData(tagInt, temp);
        if (ret <= 0) {
            return null;
        }
        result = new byte[ret];
        System.arraycopy(temp, 0, result, 0, ret);
        return result;
    }
    private String cardNumber = "";
    private final int mainKey = 2;
    //密码键盘
    private void onlinePinPad() {
    	int ret = pinPad.open(new OnSendKeyListerner() {
			
			@Override
			public void onSendKey(int keyCode) {
				messageManager.AppendInfoMessageInUiThread("keyCode-->"+keyCode);
			}
		});
    	if(ret >=0)
    	{
    		updateMainKey();
    	}
	}
    //下载主密钥
	private void updateMainKey() {
		byte[] oldKey = HexDump.hexStringToByteArray("701A5B3D7F6E891C56A46A18C1CD5C0A");
		byte[] newkey = HexDump.hexStringToByteArray("701A5B3D7F6E891C56A46A18C1CD5C0A");
		int ret = pinPad.updateMasterKey(mainKey, oldKey, newkey);
		if(ret >=0)
			updateWorkKey();
		else
			closePinpad(1);
	}
	private void closePinpad(int type){
		if(type == 1)
			messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_pinpad_main_key_error));
		else if(type == 2)
			messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_pinpad_wk_error));
		pinPad.close();
	}
	//下载工作密钥
	private void updateWorkKey() {
		byte[] pinkey = HexDump.hexStringToByteArray("5A7C9B2D21EDF2907ED9F72A5CFB6EC5");
		int ret = pinPad.updateUserKey(mainKey, 0,mainKey, pinkey);
		if(ret >=0)
			pinPadOnline();
		else
			closePinpad(2);
	}
	//获取联机pin
	private void pinPadOnline() {
		int limit = pinPad.setPinLimit(new byte[]{4,6,8});
		messageManager.AppendInfoMessageInUiThread("setLimit:"+limit);
		byte[] arryASCIICardNumber = cardNumber.getBytes();
		int nTimeout_MS = 10000;
		int nFlagSound = 1;
		messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_input_pwd));
		pinPad.calculatePinBlock(mainKey, arryASCIICardNumber, nTimeout_MS, nFlagSound,new PinPad.OnInputResultListener() {
			@Override
			public void onInputResult(int ret, byte[] result) {
				if(ret>0){
					messageManager.AppendInfoMessageInUiThread("result-->"+StringUtility.ByteArrayToString(result, ret));
					emvInterface.setOnlinePinEntered(0,new byte[]{1,2,3,4,5,6,7,8},8);
	            	int t = emvInterface.process();
	            	messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_transformation_ret)+t);
				}else{
					messageManager.AppendInfoMessageInUiThread("pin"+shower.getString(R.string.btn_pinpad_encrypt)+shower.getString(R.string.info_failed));
				}
			}
		});
	}
	
	private void closeReader(){
		boolean flag = false;
    	flag = contactlessCardReader.close() >=0;
    	flag &= smartCardReader.close()>=0;
    	if(flag)
    	{
    		messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.btn_emv_close)+shower.getString(R.string.info_success));
    	}else{
    		messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.btn_emv_close)+shower.getString(R.string.info_failed));
    	}
    }
}