package com.unionpay.acp.demo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import com.unionpay.acp.sdk.*;


/**
 * 重要：联调测试时请仔细阅读注释！
 * <p>
 * 产品：签约支付<br>
 * 交易：文件传输类接口：后台获取对账文件交易，只有同步应答 <br>
 * 日期： 2015-09<br>
 * <p>
 * 版权： 中国银联<br>
 * 声明：以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己需要，按照技术文档编写。该代码仅供参考，不提供编码，性能，规范性等方面的保障<br>
 */

public class Form36_18_FileTransfer {

    private final static Logger logger = Logger.getLogger(Form36_18_FileTransfer.class);


    public static void main(String[] args) {

        Map<String, String> contentData = new HashMap<String, String>();


        Map<String, String> data = new HashMap<String, String>();

        /***银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改***/
        data.put("version", DemoBase.version);               //版本号 全渠道默认值
        data.put("encoding", DemoBase.encoding);             //字符集编码 可以使用UTF-8,GBK两种方式
        data.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法
        data.put("txnType", "76");                           //交易类型 76-对账文件下载
        data.put("txnSubType", "01");                        //交易子类型 01-对账文件下载
        data.put("bizType", "000000");                       //业务类型，固定

        contentData.put("accessType", SDKConfig.getValueFromConfig("accessType"));
        if ("1".equals(SDKConfig.getValueFromConfig("accessType"))) {
            contentData.put("acqInsCode", SDKConfig.getValueFromConfig("acqInsCode"));//接入类型为收单机构接入时需上送
        }

        contentData.put("merId", SDKConfig.getValueFromConfig("merId"));

        contentData.put("settleDate", SDKConfig.getValueFromConfig("settleDate"));//必填，清算日期
        contentData.put("txnTime", SDKConfig.getValueFromConfig("txnTime"));
        contentData.put("fileType", SDKConfig.getValueFromConfig("fileType"));//必填，文件类型
        contentData.put("reqReserved", SDKConfig.getValueFromConfig("reqReserved"));
        //第五位取值为1时表示不返signPubKeyCert字段；

        contentData.put("ctrlRule", SDKConfig.getValueFromConfig("ctrlRule"));

        /**请求参数设置完毕，以下对请求参数进行签名并发送http post请求，接收同步应答报文------------->**/
        Map<String, String> reqData = AcpService.sign(data, DemoBase.encoding);//报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
        String url = SDKConfig.getConfig().getFileTransUrl();//获取请求银联的前台地址：对应属性文件acp_sdk.properties文件中的acpsdk.fileTransUrl
        Map<String, String> rspData = AcpService.post(reqData, url, DemoBase.encoding);

        /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
        //应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》
        String fileContentDispaly = "";
        if (!rspData.isEmpty()) {
            if (AcpService.validate(rspData, DemoBase.encoding)) {
                logger.info("验证签名成功");
                String respCode = rspData.get("respCode");
                if ("00".equals(respCode)) {
                    String outPutDirectory = "d:\\";
                    // 交易成功，解析返回报文中的fileContent并落地
                    String zipFilePath = AcpService.deCodeFileContent(rspData, outPutDirectory, DemoBase.encoding);
                    //对落地的zip文件解压缩并解析
                    List<String> fileList = DemoBase.unzip(zipFilePath, outPutDirectory);
                    //解析ZM，ZME文件
                    fileContentDispaly = "<br>获取到商户对账文件，并落地到" + outPutDirectory + ",并解压缩 <br>";
                    for (String file : fileList) {
                        if (file.indexOf("ZM_") != -1) {
                            List<Map> ZmDataList = DemoBase.parseZMFile(file);
                            fileContentDispaly = fileContentDispaly + DemoBase.getFileContentTable(ZmDataList, file);
                        } else if (file.indexOf("ZME_") != -1) {
                            DemoBase.parseZMEFile(file);
                        }
                    }
                    //TODO
                } else {
                    //其他应答码为失败请排查原因
                    //TODO
                }
            } else {
                logger.error("验证签名失败");
                //TODO 检查验证签名失败的原因
            }
        } else {
            //未返回正确的http状态
            logger.error("未获取到返回报文或返回http状态码非200");
        }

    }


}
