package com.tzy.framework.pay.service.impl;

import com.tzy.common.utils.DateUtils;
import com.tzy.framework.pay.config.QmPayZgConfig;
import com.tzy.framework.pay.dto.QmZgOrderInfoDto;
import com.tzy.framework.pay.service.QmPayAssetService;
import com.tzy.framework.pay.util.MD5Util;
import com.tzy.framework.pay.util.Util;
import com.tzy.framework.pay.util.sftp.SFtpTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.input.BOMInputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.security.cert.X509Certificate;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.tzy.framework.pay.util.Util.*;

/**
 *
 *
 */
@Slf4j
@Service
public class QmPayAssetServiceImpl implements QmPayAssetService {

    static PrivateKey batchPrivateKey = null;
    static PublicKey countPubKey = null;
    protected static MessageDigest messagedigest = null;
    @Autowired
    private QmPayZgConfig qmPayZgConfig;

    public void init(){
        try {
            //商户批量文件加签私钥--商户用
            InputStream batchPriKeyStoreFileStream = new FileInputStream(new File(qmPayZgConfig.getUpPrivateKeyPath()));
//            batchPrivateKey = getPriKeyPkcs12(batchPriKeyStoreFileStream, qmPayZgConfig.getUpPrivateKeyPwd());
            batchPrivateKey = getPriKeyPkcs12(batchPriKeyStoreFileStream, qmPayZgConfig.getUpPrivateKeyPwd());
            //回盘文件验签公钥--商户用
            InputStream countPubKeyStoreFileStream = new FileInputStream(new File(qmPayZgConfig.getUpPublicKeyPath()));
            X509Certificate countCert = X509Certificate.getInstance(countPubKeyStoreFileStream);
            countPubKey = countCert.getPublicKey();
            System.out.println("回盘验签公钥：" + countPubKey);
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("初始化失败，MessageDigest不支持MD5Util.");
        } catch (Exception e) {
            throw new RuntimeException("配置文件读取失败！");
        }
    }

    public static void init2(){
        try {
            //商户批量文件加签私钥--商户用
//            InputStream batchPriKeyStoreFileStream = new FileInputStream(new File("/home/tzy/qm/am/upPrivateKey.pfx"));
//            batchPrivateKey = getPriKeyPkcs12(batchPriKeyStoreFileStream, "123456");
            InputStream batchPriKeyStoreFileStream = new FileInputStream(new File("/home/tzy/py/pyPrivateKey.pfx"));
            batchPrivateKey = getPriKeyPkcs12(batchPriKeyStoreFileStream, "880615sandy");
            //回盘文件验签公钥--商户用
            InputStream countPubKeyStoreFileStream = new FileInputStream(new File("/home/tzy/qm/am/upPublicKey.cer"));
            X509Certificate countCert = X509Certificate.getInstance(countPubKeyStoreFileStream);
            countPubKey = countCert.getPublicKey();
            System.out.println("回盘验签公钥：" + countPubKey);
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("初始化失败，MessageDigest不支持MD5Util.");
        } catch (Exception e) {
            throw new RuntimeException("配置文件读取失败！");
        }
    }

//    public static void main(String[] args) {
////        QmPayAssetService qmPayAssetService = new QmPayAssetServiceImpl();
////        qmPayAssetService.upAtPrice02(null,null);
//        init2();
//    }

    public void upAtPrice02(List<QmZgOrderInfoDto> params,String timeStrs){
        try {
            init();
//            init2();
            String timeStr = DateUtils.parseDateToStr(DateUtils.YYYYMMDDHHMMSS, new Date());
            String timeStrYMD = DateUtils.parseDateToStr(DateUtils.YYYYMMDD, new Date());
            File file = formatStr(params,timeStr);
            String md5 = MD5Util.getFileMD5String(file);
            //签名
            byte[] signB = Util.sign(md5.getBytes(), batchPrivateKey, ALGORITHM_SHA256WITHRSA);
            File chkFile = new File("D:\\home\\tzy\\uploadpath\\qm\\02_SHPYDZ_"+timeStr+".txt.chk");
            BufferedWriter bwChk = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(chkFile)));
            bwChk.write(byteArr2HexString(signB) + "\r\n");
            bwChk.flush();
            bwChk.close();
            log.info("批量文件签名结束");
//            SFtpTools TPMX = new SFtpTools("180.169.95.129", 22, "SHPYDZ_fan", "aL1Jn$kg","/upload/", "");
            SFtpTools TPMX = new SFtpTools(qmPayZgConfig.getIp(), 22, qmPayZgConfig.getUserName(), qmPayZgConfig.getPwd(),"/upload/"+timeStrYMD+"/", "");
            TPMX.uploadFiles(file);
            TPMX.uploadFiles(chkFile);
            log.info("批量文件上传");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public File formatStr (List<QmZgOrderInfoDto> params,String timeStr){
        File file = new File("D:\\home\\tzy\\uploadpath\\qm\\02_SHPYDZ_" + timeStr + ".txt");
        try {
            String title = qmPayZgConfig.getMerchantNo() + "|" + params.size() + "\r\n";
            StringBuffer stb = new StringBuffer(title);
            if (null != params && !params.isEmpty()) {
                params.forEach(qmZgOrderInfoDto -> {
                    stb.append(qmZgOrderInfoDto.getOrderNo()).append("|")
                            .append(qmPayZgConfig.getBusinessUserNo()).append("|")
                            .append("0|")
                            .append(qmZgOrderInfoDto.getPrice()).append("\r\n");
                });
            }
            String str = stb.toString().substring(0,stb.length()-"\r\n".length());
            System.out.println("  ********************* ");
            System.out.println(str);
            BufferedWriter bwChk = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
            bwChk.write(str);
            bwChk.flush();
            bwChk.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 单个文件控制明细数不超过1万条，如超出请拆分至多个文件，间隔20分钟-+分批上传。
     * @param params
     */
    public void dwAtPrice02(List<Map<String,String>> params){
        try {
            init();
            SFtpTools TPMX = new SFtpTools(qmPayZgConfig.getIp(), 22, qmPayZgConfig.getUserName(), qmPayZgConfig.getPwd(),"", "/upload");
            File retFile = new File("D:/cert/04_000000_20190506103045.txt.ret");
            //获取签名文件中的签名
            File verRetChkFile = new File("D:/cert/04_000000_20190506103045.txt.ret.chk");
            TPMX.downloadFiles("",retFile);
            TPMX.downloadFiles("",verRetChkFile);


            String retMd5 = MD5Util.getFileMD5String(retFile);
            BufferedReader verBr = new BufferedReader(new InputStreamReader(new BOMInputStream(new FileInputStream(verRetChkFile))));
            String verSignature = verBr.readLine();
            Boolean verResult = verify(retMd5.getBytes("UTF-8"), hexString2ByteArr(verSignature) , countPubKey, ALGORITHM_SHA256WITHRSA);
            System.out.println("回盘文件验签结果:"+verResult);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 工作日9点到19点放入的文件，首次回盘在文件大约放入1小时内生成；日终回盘在第二天凌晨2点左右生成。
     */
    public void download(){

    }


}
