package com.sunyard.chsm.service;

import com.sunyard.chsm.auth.UserContext;
import com.sunyard.chsm.enums.KeyUsage;
import com.sunyard.chsm.mapper.AppCertMapper;
import com.sunyard.chsm.model.entity.AppCert;
import com.sunyard.chsm.param.*;
import com.sunyard.chsm.utils.CertUtil;
import com.sunyard.chsm.utils.CodecUtils;
import com.sunyard.chsm.utils.DateFormat;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class CertService {

    private final AppCertMapper appCertMapper;

    public ExportCertResp exportCert(ExportCertReq req) {
        boolean checkType = Objects.equals(KeyUsage.ENCRYPT_DECRYPT.getCode(), req.getCertType())
                || Objects.equals(KeyUsage.SIGN_VERIFY.getCode(), req.getCertType());
        Assert.isTrue(checkType, "证书类型错误");

        AppCert appCert = appCertMapper.selectByTypeAndDn(req.getCertType(), req.getSubject());
        Assert.notNull(appCert, "证书不存在");

        Assert.isTrue(Objects.equals(appCert.getApplicationId(), UserContext.getCurrentAppId()), "您无权导出此证书");

        ExportCertResp resp = new ExportCertResp();
        resp.setCertText(appCert.getCertText());
        return resp;
    }

    public CertInfoResp getCertInfo(String certString) {
        X509Certificate x509Certificate = CertUtil.convertToX509Cert(certString);
        CertInfoResp certInfo = new CertInfoResp();
        certInfo.setIssuerDN(x509Certificate.getIssuerDN().toString());
        certInfo.setSubjectDN(x509Certificate.getSubjectDN().toString());
        certInfo.setSerialNumber(CertUtil.getSn(certString));
        certInfo.setSigAlgName(x509Certificate.getSigAlgName());
        certInfo.setVersion(x509Certificate.getVersion());
        certInfo.setNotAfter(DateFormat.formDate(x509Certificate.getNotAfter()));
        certInfo.setNotBefore(DateFormat.formDate(x509Certificate.getNotBefore()));
        certInfo.setPublicKey(CodecUtils.encodeHex(x509Certificate.getPublicKey().getEncoded()));
        return certInfo;
    }


    public CertExinfoResp getCertExinfo(String certString) {
        X509Certificate x509Certificate = CertUtil.convertToX509Cert(certString);
        CertExinfoResp certExinfo = new CertExinfoResp();
        certExinfo.setSigAlgOID(x509Certificate.getSigAlgOID());
        certExinfo.setSignature(CodecUtils.encodeBase64(x509Certificate.getSignature()));
        return certExinfo;
    }


    public Boolean checkCert(String certString) {
        X509Certificate x509Certificate = CertUtil.convertToX509Cert(certString);
        CertCheckResp certCheck = new CertCheckResp();
        certCheck.setNotAfter(DateFormat.formDate(x509Certificate.getNotAfter()));
        certCheck.setNotBefore(DateFormat.formDate(x509Certificate.getNotBefore()));
        certCheck.setSignature(CodecUtils.encodeBase64(x509Certificate.getSignature()));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date dt = new Date();
        String nowTime = sdf.format(dt);
        boolean after = Integer.parseInt(nowTime) < Integer.parseInt(certCheck.getNotAfter());
        boolean before = Integer.parseInt(nowTime) > Integer.parseInt(certCheck.getNotBefore());
        return after && before;
    }


}
