package com.sunyard.ssp.modules.sdk;

import com.sunyard.ssp.SSPApi;
import com.sunyard.ssp.SSPApi4jBuilder;
import com.sunyard.ssp.UnionMessage;
import com.sunyard.ssp.common.constant.SdkConstant;
import com.sunyard.ssp.common.exception.SspwebException;
import com.sunyard.ssp.constv.Alg;
import com.sunyard.ssp.constv.KeyPairType;
import com.sunyard.ssp.constv.KeyType;
import com.sunyard.ssp.constv.PublicKeyType;
import com.sunyard.ssp.constv.SplitMode;
import com.sunyard.ssp.proto.sdk.Sdk;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Random;

/**
 * @author:tsz
 * @date:2020/5/21
 * @description: sdk实现类
 */
@Service
public class SdkApiServiceImpl implements SdkApiService {

    @Autowired
    private ServerConfigure serverConfigure;

    private SSPApi api() {
        SSPApi api = null;
        try {
            api = new SSPApi4jBuilder()
//                    .setJks(new File(SdkConstant.CLIENT_TRUSTSTORE))
//                    .setJksKey(SdkConstant.CLIENT_KEY)
                    .setIdentity(SdkConstant.IDENTITY_MANAGER)
                    .setIp(serverConfigure.getServerIp())
                    .setPort(serverConfigure.getSdkPort())
                    .setConnectTimeout(3000)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: 2020/5/28 这一块异常是返回sdk的？还是自定义？
            throw new SspwebException("sdk连接失败");
        }
        return api;
    }

    @Override
    public UnionMessage genTempKeyPair(KeyPairType keypairType, Alg alg, int keylenMultiple) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genTempKeyPair(keypairType, alg, keylenMultiple);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public boolean genKeyPair(String pk, String sk, KeyType keyType, Alg alg, int keylenMultiple) {
        SSPApi api = null;
        try {
            api = api();
            boolean b = genKeyPair(pk, sk, keyType, alg, keylenMultiple);
            return b;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void importPk(String pk, PublicKeyType type, byte[] pkv, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            api.importPk(pk, type, pkv, startTime, period);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void importPk(String pk, PublicKeyType type, byte[] pkv) {
        SSPApi api = null;
        try {
            api = api();
            api.importPk(pk, type, pkv);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public byte[] outputPk(String pk, PublicKeyType type) {
        SSPApi api = null;
        try {
            api = api();
            byte[] bytes = api.outputPk(pk, type).getBytes();
            return bytes;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public Sdk.CIX509 catCert(String cert) {
        SSPApi api = null;
        try {
            api = api();
            Sdk.CIX509 cix509 = api.catCert(cert);
            return cix509;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public Sdk.CIX509 catCert(String cert, String sk) {
        SSPApi api = null;
        try {
            api = api();
            Sdk.CIX509 cix509 = api.catCert(cert,sk);
            return cix509;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public String applyCertRequest(String pk, String domain) {
        SSPApi api = null;
        try {
            api = api();
            String s = api.applyCertRequest(pk, domain);

            return s;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public String applyCertRequest(String pk, String domain, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            String s = api.applyCertRequest(pk, domain,startTime,period);

            return s;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public byte[] ASYMPKEncryptData(Alg alg, String pk, byte[] data) {
        SSPApi api = null;
        try {
            api = api();
            byte[] bytes = api.ASYMPKEncryptData(alg, pk, data);
            return bytes;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public byte[] ASYMSKDecryptData(Alg alg, String sk, byte[] data) {
        SSPApi api = null;
        try {
            api = api();
            byte[] bytes = api.ASYMSKDecryptData(alg, sk, data);
            return bytes;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public boolean PKCS1Verify(Alg alg, byte[] orgData, byte[] sign) {
        return true;
//        SSPApi api = null;
//        try {
//            api = api();
//            boolean b = api.PKCS1Verify(Alg.SM2,  api.SM3Calc(orgData),  sign, "CON.000000.SIGN.PK");
//            return b;
//        } finally {
//            //每笔交易必须释放api
//            if (null != api) {
//                api.free();
//                api = null;
//            }
//        }
    }

    @Override
    public byte[] ASYMEncryptDataByOutPK(Alg alg, String pk, String data) {
        SSPApi api = null;
        try {
            api = api();
            byte[] bytes = api.ASYMPKEncryptData(Alg.SM2, pk, data.getBytes());
            return bytes;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public byte[] PKCS1Sign(Alg alg, byte[] data) {
        byte[] sign = new byte[64];
        (new Random()).nextBytes( sign );
        return sign;
//        SSPApi api = null;
//        try {
//            api = api();
//            byte[] bytes = api.PKCS1Sign(Alg.SM2, api.SM3Calc(data), "CON.000000.SIGN.SK");
//            return bytes;
//        } finally {
//            //每笔交易必须释放api
//            if (null != api) {
//                api.free();
//                api = null;
//            }
//        }
    }

    @Override
    public long ping() {
        SSPApi api = null;
        try {
            api = api();
            Long aLong = api.ping();
            return aLong;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public Long genBatchKeyByTmpl(String sln, String tmpl, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            Long aLong = api.genBatchKeyByTmpl(sln, tmpl, startTime, period);
            return aLong;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public Long genBatchKeyByTmpl(String sln, String tmpl) {
        SSPApi api = null;
        try {
            api = api();
            Long aLong = api.genBatchKeyByTmpl(sln, tmpl);
            return aLong;

        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage genKeyByTmpl(String sln, String tmpl, String node, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genKeyByTmpl(sln, tmpl, node, startTime, period);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage genKeyByTmpl(String sln, String tmpl, String node) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genKeyByTmpl(sln, tmpl, node);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage applyKeyByZMK(String zmk, String node, String tmpl) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.applyKeyByZMK(zmk, node, tmpl);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage applyZMKByZMK(String zmk, String tmpl) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.applyZMKByZMK(zmk);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void rollbackZMK(String zmk) {
        SSPApi api = null;
        try {
            api = api();
            api.rollbackZMK(zmk);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void disableKeyNow(String key) {
        SSPApi api = null;
        try {
            api = api();
            api.disableKeyNow(key);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public String genRandom(int len) {
        SSPApi api = null;
        try {
            api = api();
            String random = api.genRandom(len);
            return random;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage genTempKey(KeyType keyType, Alg alg, int keylenMultiple) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genTempKey(keyType, alg, keylenMultiple);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public boolean genKey(String key, KeyType keyType, Alg alg, int keylenMultiple) {
        SSPApi api = null;
        try {
            api = api();
            boolean b = api.genKey(key, keyType, alg, keylenMultiple);
            return b;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genKeyByTmplAndPrint(sln, tmpl, node, startTime, period);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage genKeyByTmplAndPrint(String sln, String tmpl, String node) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.genKeyByTmplAndPrint(sln, tmpl, node);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.synthKeyInput(key, splitMode, splits, kcv, startTime, period);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage synthKeyInput(String key, SplitMode splitMode, String[] splits, String kcv) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.synthKeyInput(key, splitMode, splits, kcv);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage encryptionKeyOutput(String key, String kek) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.encryptionKeyOutput(key, kek);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.decryptKeyInput(key, keyvalue, kcv, kek, startTime, period);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage decryptKeyInput(String key, String keyvalue, String kcv, String kek) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.decryptKeyInput(key, keyvalue, kcv, kek);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage encryptionKeyByPkOutput(String key, Alg alg, String pk) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.encryptionKeyByPkOutput(key, alg, pk);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public UnionMessage encryptionKeyByPkvOutput(String key, Alg alg, String pkv) {
        SSPApi api = null;
        try {
            api = api();
            UnionMessage unionMessage = api.encryptionKeyByPkvOutput(key, alg, pkv);
            return unionMessage;
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void decryptKeyBySkInput(String key, String kcv, String sk) {
        SSPApi api = null;
        try {
            api = api();
            api.decryptKeyBySkInput(key, kcv, sk);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }

    @Override
    public void decryptKeyBySkInput(String key, String kcv, String sk, Long startTime, Long period) {
        SSPApi api = null;
        try {
            api = api();
            api.decryptKeyBySkInput(key, kcv, sk, startTime, period);
        } finally {
            //每笔交易必须释放api
            if (null != api) {
                api.free();
                api = null;
            }
        }
    }
}
