import buffer from "@ohos:buffer";
import cryptoFramework from "@ohos:security.cryptoFramework";
import util from "@ohos:util";
import pako from "@normalized:N&&&pako/dist/pako.esm&2.1.0";
const gKey = "fkOurMyONOxvQi9zmHRXK9kd";
const gIv = "12345678";
export class CLStringUtil {
    public static generateRandomString(length: number): string {
        return new Array(length)
            .fill(0)
            .map(() => Math.floor(Math.random() * 36).toString(36))
            .join('');
    }
    // 字符串 -> Uint8Array
    public static stringToUint8Array(string: string, encoding: buffer.BufferEncoding = 'utf-8'): Uint8Array {
        let textEncoder = new util.TextEncoder(encoding);
        return textEncoder.encodeInto(string);
    }
    // Uint8Array -> 字符串
    public static uint8ArrayToString(src: Uint8Array, encoding: buffer.BufferEncoding = 'utf-8'): string {
        let textDecoder = new util.TextDecoder(encoding);
        return textDecoder.decodeToString(src);
    }
    // base64 string -> Uint8Array
    public static base64ToUint8Array(base64Str: string): Uint8Array {
        let base64 = new util.Base64Helper();
        return base64.decodeSync(base64Str);
    }
    // Uint8Array -> base64 string
    public static uint8ArrayToBase64(uint: Uint8Array): string {
        let base64 = new util.Base64Helper();
        return base64.encodeToStringSync(uint);
    }
    // 16进制字符串 -> unit8Array
    public static hexStringToUint8Array(hexString: string): Uint8Array {
        return new Uint8Array(buffer.from(hexString, 'hex').buffer);
    }
    // unit8Array -> 16进制字符串
    public static uint8ArrayToHexString(uint8Array: Uint8Array): string {
        return Array.from(uint8Array)
            .map(byte => byte.toString(16).padStart(2, '0'))
            .join('');
    }
}
export class CLSecurityUtils {
    public static async md5(md5String: string): Promise<string> {
        try {
            let md = cryptoFramework.createMd('MD5');
            await md.update({
                data: new util.TextEncoder().encodeInto(md5String)
            });
            let mdOutput = await md.digest();
            const toHexString = mdOutput.data.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
            return toHexString;
        }
        catch (e) {
            return '';
        }
    }
    public static async sha1(sh1String: string, secret: string): Promise<string> {
        try {
            let symKey = await cryptoFramework.createSymKeyGenerator('AES256')
                .convertKey({
                data: new util.TextEncoder().encodeInto(secret)
            });
            let sha1 = cryptoFramework.createMac('SHA1');
            await sha1.init(symKey);
            await sha1.update({
                data: new Uint8Array(buffer.from(sh1String, 'utf-8').buffer)
            });
            let mdOutput = await sha1.doFinal();
            let to64String = await new util.Base64Helper().encodeToString(mdOutput.data);
            return encodeURIComponent(to64String);
        }
        catch (e) {
            return '';
        }
    }
    public static async aes(source: string, key: string, iv: string): Promise<Uint8Array> {
        try {
            let keyData = new util.TextEncoder().encodeInto(key);
            let symKeyBlob: cryptoFramework.DataBlob = {
                data: keyData
            };
            let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
            let symKey = await aesGenerator.convertKey(symKeyBlob);
            console.info('convertKey success');
            let plainText: cryptoFramework.DataBlob = {
                data: new Uint8Array(buffer.from(source, 'utf-8').buffer)
            };
            let dataIv: Uint8Array = new util.TextEncoder().encodeInto(iv);
            let ivBlob: cryptoFramework.DataBlob = {
                data: dataIv
            };
            let symIv: cryptoFramework.IvParamsSpec = {
                algName: 'IvParamsSpec',
                iv: ivBlob
            };
            let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS5');
            await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, symIv);
            let cipherData = await cipher.doFinal(plainText);
            return cipherData.data;
        }
        catch (e) {
            return new Uint8Array();
        }
    }
    public static async aesData(sourceData: Uint8Array, key: string, iv: string): Promise<Uint8Array> {
        const source = CLStringUtil.uint8ArrayToString(sourceData);
        return await CLSecurityUtils.aes(source, key, iv);
    }
    public static async aesWithSource(sourceData: Uint8Array, key: string, iv: string, isEncrypt: boolean = true): Promise<Uint8Array> {
        try {
            let keyData = new util.TextEncoder().encodeInto(key);
            let symKeyBlob: cryptoFramework.DataBlob = { data: keyData };
            let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
            let symKey = await aesGenerator.convertKey(symKeyBlob);
            console.info('convertKey success');
            let plainText: cryptoFramework.DataBlob = {
                data: sourceData
            };
            let dataIv: Uint8Array = new util.TextEncoder().encodeInto(iv);
            let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
            let symIv: cryptoFramework.IvParamsSpec = {
                algName: 'IvParamsSpec',
                iv: ivBlob
            };
            let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
            await cipher.init(isEncrypt ? cryptoFramework.CryptoMode.ENCRYPT_MODE : cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, symIv);
            let cipherData = await cipher.doFinal(plainText);
            return cipherData.data;
        }
        catch (e) {
            console.error("code: " + e.code + " message: " + e.message);
            return new Uint8Array();
        }
    }
    public static async encryptRSA(message: string, pubKeyStr: string): Promise<Uint8Array> {
        // 服务器下发RSA公钥字符串（base64编码）
        // let pubKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFQArGDm5BXM4jHHuZGIb/kUoqrSjXkjqPLgrDmqBFxNyYsyxvyFRO10nStQwdRkQkh5lZ5sqC1G/z6lyDPpEySTBo9S5GLZ2Tj4yinNjcMXmOwiHfyQAQo9LwdlyTedwRchg0fYewWBVTVhGcWPowT1aA+GnQhYwNmaS/iKQsNQIDAQAB";
        // 初始化Base64工具实例
        let base64Helper = new util.Base64Helper();
        // 公钥转换为Uint8Array，然后包装为DataBlob类型
        let pubKeyBlob: cryptoFramework.DataBlob = {
            data: base64Helper.decodeSync(pubKeyStr)
        };
        // 创建RSA key生成器
        let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
        // 将公钥包装数据pubKeyBlob转换成密钥对类型KeyPair
        let keyPair = await rsaGenerator.convertKey(pubKeyBlob, null);
        // 创建 Cipher对象
        let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');
        // 初始化加密模式，指定密钥keyPair.pubKey
        await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
        // 包装要加密的明文
        let plainTextBlob: cryptoFramework.DataBlob = {
            data: new Uint8Array(buffer.from(message, 'utf-8').buffer)
        };
        // 传入明文，获取加密后的数据
        let encryptBlob = await cipher.doFinal(plainTextBlob);
        console.log('我的加密数据' + base64Helper.encodeToStringSync(encryptBlob.data));
        return encryptBlob.data;
        // // 返回加密后的字符串
        // return base64Helper.encodeToStringSync(encryptBlob.data);
    }
    // public static async decryptRSAString(base64Message:string,privateKeyStr: string):Promise<string>{
    //   // let base64Helper = new util.Base64Helper();
    //   // const decryptData =  base64Helper.decodeSync(base64Message)
    //
    //   const decryptData =  new Uint8Array(buffer.from(base64Message, 'utf-8').buffer)
    //   const  res = await CLSecurityUtils.decryptRSA(decryptData,privateKeyStr)
    //   console.log('调用啦---------1')
    //   return Promise.race(res)
    // }
    public static async decryptRSAString(encryptedBase64: string, pubKeyBase64: string): Promise<string> {
        try {
            let base64Helper = new util.Base64Helper();
            // 创建 verifier
            const verifier = cryptoFramework.createVerify('RSA1024|PKCS1|NoHash|Recover');
            // 构造公钥数据
            const pubKeyBlob: cryptoFramework.DataBlob = {
                data: base64Helper.decodeSync(pubKeyBase64)
            };
            let generator = cryptoFramework.createAsyKeyGenerator('RSA1024');
            let keyPair = await generator.convertKey(pubKeyBlob, null);
            await verifier.init(keyPair.pubKey);
            // 构造签名密文数据
            const encryptedBlob: cryptoFramework.DataBlob = {
                data: base64Helper.decodeSync(encryptedBase64)
            };
            // 使用 recover 恢复明文
            const recoveredBlob = await verifier.recover(encryptedBlob);
            if (!recoveredBlob || !recoveredBlob.data) {
                throw new Error('recover failed, result is null');
            }
            const decoder = new util.TextDecoder('utf-8');
            const result = decoder.decode(recoveredBlob.data);
            return result;
        }
        catch (err) {
            throw new Error(`publicKeyDecryptByRecover error: ${(err as Error).message}`);
        }
    }
    public static async decryptRSA(encryptedData: string, privateKeyStr: string): Promise<string> {
        // 初始化Base64工具
        let base64Helper = new util.Base64Helper();
        console.log('调用啦---------3');
        // 将 base64 编码的私钥字符串转为 DataBlob
        let privKeyBlob: cryptoFramework.DataBlob = {
            data: base64Helper.decodeSync(privateKeyStr) // base64转Uint8Array
        };
        // 创建 RSA 密钥生成器（和加密时一致）
        let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
        // 转换为 keyPair（只有私钥）
        let keyPair = await rsaGenerator.convertKey(null, privKeyBlob);
        // 创建 Cipher
        let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');
        // 初始化为解密模式
        await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
        // 包装加密数据为 DataBlob
        let encryptedBlob: cryptoFramework.DataBlob = {
            data: base64Helper.decodeSync(encryptedData)
        };
        let plainBlob = await cipher.doFinal(encryptedBlob);
        console.log('调用啦---------2');
        // 转换解密结果为字符串
        let decoder = new util.TextDecoder('utf-8');
        let result = decoder.decode(plainBlob.data);
        console.log('解密结果:', result);
        return result;
    }
}
export class CLGzipUtil {
    public static async gzipAndAES(data: Uint8Array, random: string): Promise<Uint8Array> {
        if (random.length !== 32) {
            random = 'aqwe1122re3ew90tr43w24rvvbfgsgsf';
        }
        const key = random.substring(0, 16);
        const iv = random.substring(16);
        let gzipData = CLGzipUtil.gzipCompress(data);
        let aesData = await CLSecurityUtils.aesWithSource(gzipData, key, iv);
        return aesData;
    }
    public static gzipCompress(data: Uint8Array): Uint8Array {
        let gzData: Uint8Array | undefined = pako.gzip(data);
        if (gzData !== undefined) {
            console.log('压缩成功啦');
            return gzData;
        }
        else {
            return new Uint8Array();
        }
    }
    public static ungzipCompress(data: Uint8Array): Uint8Array | string {
        let gzData: Uint8Array | string | undefined = pako.ungzip(data);
        if (gzData !== undefined) {
            return gzData;
        }
        else {
            return '';
        }
    }
}
