import CryptoJS from 'crypto-js';

export class Encrypt {
    static encrypt(buf: string | object | Uint8Array): string | object | Uint8Array {
        // if (buf instanceof Uint8Array && !buf.encrypt) {
        //     return encryptUint8Array(buf);
        // }
        return buf;
    }
    static decrypt(buf: string | object | Uint8Array): string | object | Uint8Array {
        if (buf instanceof Uint8Array) {
            return decryptUint8Array(buf);
        }
        return buf;
    }
}

let aIv = [0x15, 0x4C, 0xD3, 0x55, 0xFE, 0xA1, 0xFF, 0x01, 0x00, 0x34, 0xAB, 0x22, 0x08, 0x4F, 0x13, 0x07];
let aKey = [0x26, 0xAF, 0xE2, 0x1A, 0x0C, 0x16, 0x73, 0x54, 0x13, 0xFD, 0x68, 0xDD, 0x8F, 0xA0, 0xB7, 0xC1, 0x57, 0xA6, 0x90, 0xFF, 0xCD, 0xB3, 0x54, 0x61, 0x10, 0x07, 0xD5, 0x7E, 0xDB, 0x1E, 0x4C, 0xE9];
let ivBv = new Uint8Array(aIv);
let keyBv = new Uint8Array(aKey);
let u8array = {
    parse: function (u8arr: Uint8Array) {
        var len = u8arr.length;
        var words = [];
        for (var i = 0; i < len; i++) {
            words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
        }
        return CryptoJS.lib.WordArray.create(words, len);
    },
    stringify: function (wordArray: CryptoJS.lib.WordArray) {
        var words = wordArray.words;
        var sigBytes = wordArray.sigBytes;
        var u8 = new Uint8Array(sigBytes);
        for (var i = 0; i < sigBytes; i++) {
            var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
            u8[i] = byte;
        }
        return u8;
    }
};

const keyWA = u8array.parse(keyBv);
const ivWA = u8array.parse(ivBv);

export function encryptUint8Array(array: Uint8Array) {
    for (let i = 0; i < array.length; ++i) {
        array[i] -= 1;
    }
    let contentWA = u8array.parse(array);
    // let dcBase64String = contentWA.toString(CryptoJS.enc.Base64);
    let encrypted = CryptoJS.AES.encrypt(contentWA, keyWA, {
        iv: ivWA,
        mode: CryptoJS.mode.CFB,
        padding: CryptoJS.pad.NoPadding
    });
    let u8 = u8array.stringify(encrypted.ciphertext);
    return u8;
}

function decryptUint8Array(array: Uint8Array) {
    let contentWA = u8array.parse(array);
    let dcBase64String = contentWA.toString(CryptoJS.enc.Base64);
    let decrypted = CryptoJS.AES.decrypt(dcBase64String, keyWA, {
        iv: ivWA,
        mode: CryptoJS.mode.CFB,
        padding: CryptoJS.pad.NoPadding
    });
    let buf = u8array.stringify(decrypted);
    for (let i = 0; i < buf.length; ++i) {
        buf[i] += 1;
    }
    return buf;
}
