package com.dbs.mplus.fatima.consent.sign;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.text.InputType;
import android.text.method.PasswordTransformationMethod;
import android.util.Base64;
import android.widget.EditText;

import com.androidKmi.KmiApi;
import com.dbs.mplus.fatima.consent.ConsentConstants;
import com.dbs.mplus.fatima.framework.util.MPlusLogUtil;
import com.dbs.mplus.fatima.framework.view.dialog.MPlusDialog;
import com.lumensoft.ks.KSCertificate;
import com.lumensoft.ks.KSCertificateLoader;
import com.lumensoft.ks.KSCertificateManager;
import com.lumensoft.ks.KSException;
import com.lumensoft.ks.KSSign;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * 전자서명 Wrapper
 * Created by dbs on 2016-10-06.
 */

public class SignWrapper {

    private static SignWrapper instance;
    private final KmiApi kmiApi;

    private Map<String, CertificateInfo> certificateMap;

    private SignWrapper() {
        this.kmiApi = new KmiApi();
        this.certificateMap = new HashMap<String, CertificateInfo>();
    }

    public static SignWrapper getInstance() {
        if(instance == null) {
            instance = new SignWrapper();
        }
        return instance;
    }

    /**
     * 인증서 모두 삭제
     */
    public void destroyCertificate() {
        MPlusLogUtil.INFO(this.getClass(), "인증서 모두 제거 - " + this.certificateMap.size());
        for(CertificateInfo certInfo : this.certificateMap.values()) {
            KSCertificateManager.deleteCert(certInfo.getCertificate());
        }
        this.certificateMap.clear();
    }

    public void deleteAll() {
        String dn = "ou=대구파티마병원,ou=의료,o=SignKorea,c=KR";
        boolean result = this.kmiApi.CertBatchDel(dn);
        this.certificateMap.clear();
        MPlusLogUtil.INFO(this.getClass(), "인증서 모두 제거 성공여부 - " + result + ", dn:" + dn);
    }

    /**
     * 인증여부 확인
     * @param userId
     * @return
     */
    public boolean isCertificate(String userId) {
        return this.certificateMap.containsKey(userId);
    }

    /**
     * 인증서 인증
     * @param context
     * @param userId
     * @param password
     * @return
     * @throws UnsupportedEncodingException
     * @throws KSException
     */
    public boolean certificate(Context context, String userId, String password) throws Exception {
        // 인증서 다운로드
        String certDN = this.downloadCertificate(userId);
        // 인증서 다운로드 실패
        if(certDN == null) {
            return false;
        }
        // 인증서 목록 가져와서
        Vector<KSCertificate> certificateVector = KSCertificateLoader.getUserCertificateList(context);
        // 사용자 인증서 꺼내오고
        int index = KSCertificateLoader.getUserCertificate(certDN, context);
        // 인증서가 존재하지 않으면 실패
        if(index < 0) {
            return false;
        }
        KSCertificate certificate = certificateVector.get(index);
        if(KSCertificateManager.checkPwd(certificate, password)) {
            // 인증된 목록 저장
            CertificateInfo certInfo = new CertificateInfo(certificate, password);
            this.certificateMap.put(userId, certInfo);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 서명
     * @param userId
     * @param signData
     * @return
     */
    public String signData(String userId, String signData) {
        String certResult = null;
        CertificateInfo certificate = this.certificateMap.get(userId);
        if(certificate != null) {
            try {
                byte[] result = null;
                // 서명데이터 구분자 ^ 빼고
                String hashValue = signData.replaceAll("\\^", "");
                MPlusLogUtil.DEBUG(this.getClass(), "동의서 전자서명 시작 ^문자 제거:" + hashValue);
                result = KSSign.koscomSign(certificate.getCertificate(), hashValue, certificate.getPassword());
                certResult = new String(Base64.encode(result, Base64.DEFAULT));
            } catch (KSException e) {
                e.printStackTrace();
            }
        }
        return certResult;
    }

    public String getCertificateInfo() {
        return this.certificateMap.toString();
    }

    /**
     * KMI 인증서 다운로드
     * @param userId
     * @return 사용자 아이디
     */
    private String downloadCertificate(String userId) throws Exception {
        String certDN = null;
        MPlusLogUtil.DEBUG(this.getClass(), "인증서버 연결:" + ConsentConstants.CERT_SERVER_IP + "(" + ConsentConstants.CERT_SERVER_PORT + ")");
        if(kmiApi.kmsConnect(ConsentConstants.CERT_SERVER_IP, ConsentConstants.CERT_SERVER_PORT)) {
            MPlusLogUtil.DEBUG(this.getClass(), "인증서버 연결성공");
            certDN = kmiApi.GetKeyAndCert(userId);
            MPlusLogUtil.DEBUG(this.getClass(), "인증서 가져오기: " + userId + "-" + certDN);
            kmiApi.kmsDisconnect();
            //kmiApi.CertBatchDel("ou=테스트지점,ou=테스트회사,ou=테스트업종,o=SignKorea,c=KR")
            MPlusLogUtil.DEBUG(this.getClass(), "인증서버 연결해제");
        } else {
            MPlusLogUtil.DEBUG(this.getClass(), "인증서버 연결실패  KMIAPI 에러메시지:" + kmiApi.errorMsg());
            throw new Exception("인증서버 연결실패 - " + kmiApi.errorMsg());
        }
        return certDN;
    }
}
