import com.google.gson.Gson;
import org.chainweaver.did.sdk.exception.ChainWeaverException;
import org.chainweaver.did.sdk.model.*;
import org.chainweaver.did.sdk.model.req.*;
import org.chainweaver.did.sdk.model.resp.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.*;

public class TestDId extends TestBase {


//    @Test
//    public void login(){
//        Response<AccessToken> accessToken = didClient.login("ac", "caa");
//        System.out.println("【】 "+accessToken.toString());
//    }

    @Test
    public void health() throws ChainWeaverException {
        Response<DidHealth> didHealthResponse = didClient.health();
        System.out.println("【health】 " + didHealthResponse.toString());
        Assertions.assertEquals(didHealthResponse.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void msgEncrypt() throws ChainWeaverException {
        // 示例一
        String plainText = Base64.getEncoder().encodeToString(("hello world".getBytes()));
        Plaintext plaintext = Plaintext.genMsgEncryptWithBase64(plainText, "did:cnbn:6b3e32f9438045e4917505304e19f9a4#key-1");
        // 示例二
        // Plaintext plaintext = Plaintext.genMsgEncrypt("hello world", "did:cnbn:08aa00ee260142c58ccaf2a2536495dd#key-1");
        plaintext.setType("SM2C1C3C2");
        Response<Cipher> res = didClient.msgEncrypt(plaintext);
        System.out.println("【msgEncrypt】 " + res.toString());
        Assertions.assertEquals(res.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void msgDecrypt() throws ChainWeaverException {
        // 示例一
        String plainText = Base64.getEncoder().encodeToString(("hello world".getBytes()));
        Plaintext plaintext = Plaintext.genMsgEncryptWithBase64(plainText, "did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");
        // 示例二
        // Plaintext plaintext = Plaintext.genMsgEncrypt("hello world", "did:cnbn:08aa00ee260142c58ccaf2a2536495dd#key-1");
        plaintext.setType("SM2C1C3C2");
        Response<Cipher> cipherResponse = didClient.msgEncrypt(plaintext);
        Response<Plaintext> res = didClient.msgDecrypt(cipherResponse.getData());
        System.out.println("【msgDecrypt】 " + res.toString());
        Assertions.assertEquals(res.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void msgVerify() throws ChainWeaverException {
        msgSign();
//        String msgStr = "{" +
//                "\"plaintext\":\"hello world\"," +
//                "\"signature\":\"MEQCIDGTkracktvQtkHxOOLlDvLaRTbwCSE8JueRIZ2TnjizAiAXUHmTkEE7DKzMwRt7KYF4TMZh5/+A1Rcq8xvn6Ef4ZA==\"," +
//                "\"verificationMethod\":\"did:cnbn:5c124dcb445544338afacfa8182f620a#key-1\"" +
//                "}";
//        Gson gson = new Gson();
//        Plaintext plaintext = gson.fromJson(msgStr, Plaintext.class);
//        Response<Boolean> code = didClient.msgVerify(plaintext);
//        System.out.println("【msgVerify】 "+code.toString());
    }

    @Test
    public void msgSign() throws ChainWeaverException {
        // 示例一
        String plainText = Base64.getEncoder().encodeToString(("hello world".getBytes()));
        Plaintext plaintext = Plaintext.genMsgSignWithBase64(plainText, "did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");
        // 示例二
//        Plaintext plaintext = Plaintext.genMsgSign("hello world", "did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");
        plaintext.setType("SM2Signature");
        Response<Plaintext> res = didClient.msgSign(plaintext);
        System.out.println("【msgSign】 " + res.toString());
        res.getData().setPlaintext(plainText);
        Response<Boolean> code = didClient.msgVerify(res.getData());
        System.out.println("【msgSign】 " + code.toString());
        Assertions.assertEquals(res.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vpVerify() throws ChainWeaverException {
        vpSign();
//        String proofValue = "eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6ZXhhbXBsZToxMjM0NTY3ODlhYmNkZWZnaGlfa2V5LTEiLCJ0eXAiOiJKV1MifQ9JYDNOU0oyJkXW5NcC1hR3U4SHN6U1RiY3pvYkUzam5vY3VtY2tjZERxY3dLd1Z0a1d0Z2pUa0dWY3A0bFZJZw";
//        String vpStr = "{" +
//                "  \"@context\": [" +
//                "    \"https://cnbn.org.cn\"" +
//                "  ]," +
//                "  \"id\": \"2024-04-03 10:14:53.408944687 +0000 UTC m\\u003d+57.374104496fdab4289b3644fd0b89bcec103a1a19f\"," +
//                "  \"type\": \"VerifiablePresentation\"," +
//                "  \"presentationUsage\": \"DID_GET_IDENTITY_VC_REQUEST\"," +
//                "  \"expirationDate\": \"2024-04-03T18:19:53Z\"," +
//                "  \"extend\": {" +
//                "    \"authorizedName\": \"xx平台\"," +
//                "    \"fileID\": \"did:cnbn:qiye01@0x4a3e3f4a5f88x9f00e0a0f86\"," +
//                "    \"fileName\": \"xx文件.pdf\"" +
//                "  }," +
//                "  \"proof\": [" +
//                "    {" +
//                "      \"type\": \"SM2Signature\"," +
//                "      \"created\": \"2024-04-03T10:14:53Z\"," +
//                "      \"proofPurpose\": \"assertionMethod\"," +
//                "      \"verificationMethod\": \"did:cnbn:5c124dcb445544338afacfa8182f620a#key-1\"," +
//                "      \"proofValue\": \"MEQCIAkGSwjpOijlwtYgce1ZLHbIjHpyV/SQit2L7VvxeFO7AiAsMfAyBVXMU3dAzW16f7jlzQZJlrSbflEgiiNDNU62Ig\\u003d\\u003d\"" +
//                "    }" +
//                "  ]," +
//                "  \"timestamp\": \"2024-04-03T10:14:53Z\"" +
//                "}";
//        Gson gson = new Gson();
//        // 验证VP 结合申请VP使用
//        // 在申请Vp增加了验证vp
//        VerifiablePresentation vp = gson.fromJson(vpStr, VerifiablePresentation.class);
//        Response<Boolean> code = didClient.vpVerify(vp);
//        System.out.println("【vpVerify】 "+code.toString());
    }

    static class VpSignExtend {

        private String authorizedName;

        private String fileID;

        private String fileName;


        public String getFileID() {
            return fileID;
        }

        public void setFileID(String fileID) {
            this.fileID = fileID;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public String getAuthorizedName() {
            return authorizedName;
        }

        public void setAuthorizedName(String authorizedName) {
            this.authorizedName = authorizedName;
        }

        public VpSignExtend(String fileID, String fileName, String authorizedName) {
            this.fileID = fileID;
            this.fileName = fileName;
            this.authorizedName = authorizedName;
        }
    }

    @Test
    public void vpSign() throws ChainWeaverException {
        // 设置需要哪个私钥签名
        Proof proof = new Proof("");
        // 构建业务逻辑参数,VpSignExtend临时示例对象
        VpSignExtend extend = new VpSignExtend("did:cnbn:qiye01@0x4a3e3f4a5f88x9f00e0a0f86", "xx文件.pdf", "xx平台");
        // 构建VP结构体
        VerifiablePresentation<VpSignExtend> vp = new VerifiablePresentation<>(null, Collections.singletonList(proof));
        vp.setPresentationUsage(PresentationUsage.DID_GET_IDENTITY_VC_REQUEST);
        // 设置业务逻辑参数
        vp.setExtend(extend);
        Response<VerifiablePresentation<VpSignExtend>> res = didClient.vpSign(vp, VpSignExtend.class);
        Response<Boolean> code = didClient.vpVerify(res.getData());
        System.out.println("【vpSign】 " + res);
        System.out.println("【vpSign】 " + code.toString());
        Assertions.assertEquals(code.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vpCreateApplyBusinessLicense() throws ChainWeaverException {
        Proof proof = new Proof("did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");

        ApplyBusinessLicenseExtend extend = new ApplyBusinessLicenseExtend(Collections.singletonList("did:cnbn:wxb"), "https://xxx.com/callback/identity");
        VerifiablePresentation<ApplyBusinessLicenseExtend> vp = VerifiablePresentation.vpCreateApplyBusinessLicense(new ArrayList<>(Collections.singleton(proof)));
        vp.setExtend(extend);
        Response<VerifiablePresentation<ApplyBusinessLicenseExtend>> res = didClient.vpCreateApplyBusinessLicense(vp);
        System.out.println("【vpCreateApplyBusinessLicense】 " + res.toString());
        System.out.println("【vpCreateApplyBusinessLicense】 " + res.getData().getExtend().getIssuer());
        Assertions.assertEquals(res.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vpCreateApplyLogin() throws ChainWeaverException {
        Proof proof = new Proof("");
        VerifiablePresentation<LoginExtend> vp = VerifiablePresentation.vpCreateApplyLogin(new ArrayList<>(Collections.singleton(proof)));
        LoginExtend loginExtend = new LoginExtend("https://xxx.com/callback/identity");
        vp.setExtend(loginExtend);
        Response<VerifiablePresentation<LoginExtend>> res = didClient.vpCreateApplyLogin(vp);
        System.out.println("【vpCreateApplyLogin】 " + res.toString());
        Assertions.assertEquals(res.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void documentGet() throws ChainWeaverException {
        Response<Document> document = didClient.documentGet("did:cnbn:5c124dcb445544338afacfa8182f620a");
        if (document != null && Objects.equals(document.getCode(), StatusCode.SUCCESS.getCode())) {
            System.out.println("【documentGet】 " + document);
        } else {
            assert document != null;
            System.out.println("【documentGet】 " + document.getMessage() + " " + document.getCode());
        }
        Assertions.assertEquals(document.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vcIssue() throws ChainWeaverException {
        CredentialSubject credentialSubject = new CredentialSubject("xxx平台用户证书", "xxx企业", "52110000MJ1151545K");

        IssueVc issueVc = new IssueVc("100013", credentialSubject, "did:cnbn:cnbn", "did:cnbn:cnbn#key-1");

        Response<VerifiableCredential> vc = didClient.vcIssue(issueVc);
        System.out.println("【vcIssue】 " + vc.toString());
        Response<VcInfo> vcInfo = didClient.vcGet(vc.getData().getId());
        System.out.println("【vcIssue】 " + vcInfo.toString());
        Assertions.assertEquals(vcInfo.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vcRevoke() throws ChainWeaverException {
        CredentialSubject credentialSubject = new CredentialSubject("xxx平台用户证书", "xxx企业", "52110000MJ1151545K");

        IssueVc issueVc = new IssueVc("100013", credentialSubject, "did:cnbn:cnbn", "did:cnbn:cnbn#key-1");

        Response<VerifiableCredential> vc = didClient.vcIssue(issueVc);
        Response<Boolean> code = didClient.vcRevoke(vc.getData().getId());
        System.out.println("【vcRevoke】 " + code.toString());
        Assertions.assertEquals(code.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void issuedList() throws ChainWeaverException {
        Holder holder = new Holder("did:cnbn:5c124dcb445544338afacfa8182f620a#key-1", 1, 20);
        Response<RespPage<VerifiableCredential>> resp = didClient.vcListIssued(holder);
        System.out.println("【issuedList】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void revokedList() throws ChainWeaverException {
        Holder holder = new Holder("did:cnbn:5c124dcb445544338afacfa8182f620a#key-1", 1, 20);
        Response<RespPage<VerifiableCredential>> resp = didClient.vcListRevoked(holder);
        System.out.println("【revokedList】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    static class VcListTest {
        private String templateId;

        public String getTemplateId() {
            return templateId;
        }

        public void setTemplateId(String templateId) {
            this.templateId = templateId;
        }

        public Page getPage() {
            return page;
        }

        public void setPage(Page page) {
            this.page = page;
        }

        public String getIssuer() {
            return issuer;
        }

        public void setIssuer(String issuer) {
            this.issuer = issuer;
        }

        private Page page;

        private String issuer;


        public VcListTest(String templateId, Page page, String issuer) {
            this.templateId = templateId;
            this.page = page;
            this.issuer = issuer;
        }
    }

    @Test
    public void vcList2() throws ChainWeaverException {

        CredentialSubject credentialSubject = new CredentialSubject("xxx平台用户证书", "xxx企业", "52110000MJ1151545K");
        IssueVc issueVc = new IssueVc("100013", credentialSubject, "did:cnbn:5c124dcb445544338afacfa8182f620a", "");
        Response<VerifiableCredential> vc = didClient.vcIssue(issueVc);
        System.out.println(new Gson().toJson(vc));

        Proof proof = new Proof("did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");
        VcListTest vcListTest = new VcListTest("100013", new Page(1, 20), "did:cnbn:5c124dcb445544338afacfa8182f620a");
//        构建业务逻辑参数,VpSignExtend临时示例对象
        VerifiablePresentation<VcListTest> vp = new VerifiablePresentation<>(null, new ArrayList<>(Collections.singleton(proof)));

        // 构建VP结构体
        vp.setType("SM2C1C3C2");
        vp.setPresentationUsage("DID_GET_IDENTITY_VC_REQUEST");
        vp.setExtend(vcListTest);
        Response<VerifiablePresentation<VcListTest>> res = didClient.vpSign(vp, VcListTest.class);
        System.out.println(new Gson().toJson(res.getData()));

        res.getData().getProof().forEach(proof1 -> proof1.setType("SM2C1C3C2"));
        Response<RespPage<VerifiableCredential>> resp = didClient.vcList(res.getData());
        System.out.println("【vcList】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vcList() throws ChainWeaverException {
        // 给用户did:cnbn:5c124dcb445544338afacfa8182f620a签发一个VC
        CredentialSubject credentialSubject = new CredentialSubject("xxx平台用户证书", "xxx企业", "52110000MJ1151545K");
        IssueVc issueVc = new IssueVc("100013", credentialSubject, "did:cnbn:5c124dcb445544338afacfa8182f620a", "");
        Response<VerifiableCredential> vc = didClient.vcIssue(issueVc);
        System.out.println("【vcList】 vc:" + new Gson().toJson(vc));

        // 查询用户did:cnbn:5c124dcb445544338afacfa8182f620a的所有VC
        Proof proof = new Proof("did:cnbn:5c124dcb445544338afacfa8182f620a#key-1");
        VcListTest vcListTest = new VcListTest("100013", new Page(1, 20), "did:cnbn:5c124dcb445544338afacfa8182f620a");
        VerifiablePresentation<VcListTest> vp = new VerifiablePresentation<>(null, Collections.singletonList(proof));
        vp.setType("SM2C1C3C2");
        vp.setPresentationUsage("DID_GET_IDENTITY_VC_REQUEST");
        vp.setExtend(vcListTest);
        Response<VerifiablePresentation<VcListTest>> res = didClient.vpSign(vp, VcListTest.class);
        System.out.println("【vcList】 请求获取vc的vp:" + new Gson().toJson(res.getData()));

        res.getData().getProof().forEach(proof1 -> proof1.setType("SM2C1C3C2"));
        Response<RespPage<VerifiableCredential>> resp = didClient.vcList(res.getData());
        System.out.println("【vcList】 vc列表:" + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vcGet() throws ChainWeaverException {
        vcIssue();
    }

    @Test
    public void vcListLatest() throws ChainWeaverException {
        Response<Boolean> resp = didClient.vcListLatest("did:cnbn:yh#key1", 1);
        System.out.println("【vcListLatest】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vcListLocal() throws ChainWeaverException {
        VcListVo vcListVo = new VcListVo(1, 20, "202403040120000-0000001", "");
        Response<RespPage<VerifiableCredential>> resp = didClient.vcListLocal(vcListVo);
        System.out.println("【vcListLocal】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

    @Test
    public void vctemplateCreate() throws ChainWeaverException {
        // 构建业务逻辑参数
        Map<String, Property> propertyMap = new HashMap<>();
        propertyMap.put("code", new Property("string", "统一社会信用代码", "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", ""));
        VCTExtend extend = new VCTExtend(propertyMap, new ArrayList<>(Collections.singleton("code")), "xx平台用户凭证", "v1.0", true, "");
        // 发送
        Response<VctId> vctId = didClient.vctemplateCreate(extend);
        System.out.println("【vctemplateCreate】 " + vctId.toString());
        Assertions.assertEquals(vctId.getCode(), StatusCode.SUCCESS.getCode());
    }


    @Test
    public void vctemplateList() throws ChainWeaverException {
        VcTemplateListVo vcTemplateListVo = new VcTemplateListVo(1, 20, "100001", "xx平台用户凭证", "v1.0");
        Response<RespPage<VcTInfo>> resp = didClient.vctemplateList(vcTemplateListVo);
        System.out.println("【vctemplateList】 " + resp.toString());
        Assertions.assertEquals(resp.getCode(), StatusCode.SUCCESS.getCode());
    }

}