package com.cf.imes.module.system.util.rsa;

import org.junit.jupiter.api.Test;

import java.util.LinkedList;

import static org.junit.jupiter.api.Assertions.*;

/**
 * {@link AsymmetricAlgorithmUtil} 的单元测试
 */
class AsymmetricAlgorithmUtilTest {

    @Test
    void testGetPriKeyAndPubKey() {
        // 测试获取公私钥集合
        LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();

        assertNotNull(keys);
        assertEquals(2, keys.size());
        assertNotNull(keys.get(0)); // 私钥
        assertNotNull(keys.get(1)); // 公钥
        assertNotEquals(keys.get(0), keys.get(1)); // 私钥和公钥应该不同
    }

    @Test
    void testEncryptByPublicAndDecryptByPrivate() {
        // 测试公钥加密私钥解密
        LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey = keys.get(0);
        String publicKey = keys.get(1);
        String plainText = "Hello World! 你好世界！";

        // 公钥加密
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
        assertNotNull(encryptedText);
        assertNotEquals(plainText, encryptedText); // 加密后的文本应该与原文不同

        // 私钥解密
        String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
        assertEquals(plainText, decryptedText); // 解密后的文本应该与原文相同
    }

    @Test
    void testEncryptByPrivateAndDecryptByPublic() {
        // 测试私钥加密公钥解密
        LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey = keys.get(0);
        String publicKey = keys.get(1);
        String plainText = "Hello World! 你好世界！";

        // 私钥加密
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPrivate(plainText, privateKey);
        assertNotNull(encryptedText);
        assertNotEquals(plainText, encryptedText); // 加密后的文本应该与原文不同

        // 公钥解密
        String decryptedText = AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, publicKey);
        assertEquals(plainText, decryptedText); // 解密后的文本应该与原文相同
    }

    @Test
    void testEncryptAndDecryptWithEmptyString() {
        // 测试空字符串的加解密
        LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey = keys.get(0);
        String publicKey = keys.get(1);
        String plainText = "";

        // 公钥加密空字符串
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
        assertNotNull(encryptedText);

        // 私钥解密
        String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
        assertEquals(plainText, decryptedText);
    }

    @Test
    void testEncryptAndDecryptWithSpecialCharacters() {
        // 测试特殊字符的加解密
        LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey = keys.get(0);
        String publicKey = keys.get(1);
        String plainText = "Hello\nWorld!\t你好\r世界！@#$%^&*()";

        // 公钥加密
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
        assertNotNull(encryptedText);
        assertNotEquals(plainText, encryptedText);

        // 私钥解密
        String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
        assertEquals(plainText, decryptedText);
    }

    @Test
    void testEncryptByPublicWithInvalidKey() {
        // 测试使用无效公钥加密
        String plainText = "Hello World";
        String invalidPublicKey = "invalid-public-key";

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.encryptByPublic(plainText, invalidPublicKey);
        });
    }

    @Test
    void testDecryptByPrivateWithInvalidKey() {
        // 测试使用无效私钥解密
        String encryptedText = "some-encrypted-text";
        String invalidPrivateKey = "invalid-private-key";

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, invalidPrivateKey);
        });
    }

    @Test
    void testEncryptByPrivateWithInvalidKey() {
        // 测试使用无效私钥加密
        String plainText = "Hello World";
        String invalidPrivateKey = "invalid-private-key";

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.encryptByPrivate(plainText, invalidPrivateKey);
        });
    }

    @Test
    void testDecryptByPublicWithInvalidKey() {
        // 测试使用无效公钥解密
        String encryptedText = "some-encrypted-text";
        String invalidPublicKey = "invalid-public-key";

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, invalidPublicKey);
        });
    }

    @Test
    void testDecryptByPrivateWithWrongKey() {
        // 测试使用不匹配的私钥解密
        LinkedList<String> keys1 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String publicKey1 = keys1.get(1);
        String plainText = "Hello World";

        // 使用第一组密钥加密
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey1);

        // 使用第二组密钥解密（不匹配的私钥）
        LinkedList<String> keys2 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey2 = keys2.get(0);

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey2);
        });
    }

    @Test
    void testDecryptByPublicWithWrongKey() {
        // 测试使用不匹配的公钥解密
        LinkedList<String> keys1 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String privateKey1 = keys1.get(0);
        String plainText = "Hello World";

        // 使用第一组密钥加密
        String encryptedText = AsymmetricAlgorithmUtil.encryptByPrivate(plainText, privateKey1);

        // 使用第二组密钥解密（不匹配的公钥）
        LinkedList<String> keys2 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
        String publicKey2 = keys2.get(1);

        assertThrows(Exception.class, () -> {
            AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, publicKey2);
        });
    }
}