import * as fflate from 'fflate'

/**
 * 使用deflate算法压缩文件
 * @param data 
 */
export function Deflate(data: Uint8Array | string): Uint8Array {
    if (typeof data === 'string')
        data = StrToU8(data);
    return fflate.deflateSync(data);
}

/**
 * 异步地使用deflate算法压缩文件
 * @param data 
 */
export function DeflateAsync(data: Uint8Array | string): Promise<Uint8Array> {
    if (typeof data === 'string')
        data = StrToU8(data);
    return new Promise<Uint8Array>((resolve, reject) => {
        const termiante = fflate.deflate(data as Uint8Array, (err, result) => {
            if (err)
                reject(err.message);
            else
                resolve(result);
        })
    })
}


/**
 * 使用Zlib压缩文件
 * @param data 
 */
export function Zlib(data: Uint8Array | string): Uint8Array {
    if (typeof data === "string")
        data = fflate.strToU8(data);
    return fflate.zlibSync(data);
}

/**
 * 异步地使用Zlib压缩文件
 * @param data 
 */
export async function ZlibAsync(data: Uint8Array | string): Promise<Uint8Array> {
    if (typeof data === 'string')
        data = StrToU8(data);
    return new Promise<Uint8Array>((resolve, reject) => {
        const terminate = fflate.zlib(data as Uint8Array, (err, result) => {
            if (err)
                reject(err.message);
            else
                resolve(result);
        });

    })
}

/**
 * 创建zip文件
 * @param data Zip格式对象
 */
export function Zip(data: fflate.Zippable): Uint8Array {
    return fflate.zipSync(data);
}

/**
 * 异步地创建zip文件
 * @param data Zip格式对象
 */
export async function ZipAsync(data: fflate.Zippable): Promise<Uint8Array> {
    return new Promise<Uint8Array>((resolve, reject) => {
        const terminate = fflate.zip(data, (err, result) => {
            if (err)
                reject(err.message);
            else
                resolve(result);
        });
    });
}

/**
 * 解压Zip文件
 * @param data 
 */
export function Unzip(data: Uint8Array): fflate.Unzipped {
    return fflate.unzipSync(data);
}

/**
 * 异步地解压Zip文件
 * @param data 
 */
export function UnzipAsync(data: Uint8Array): Promise<fflate.Unzipped> {
    return new Promise<fflate.Unzipped>((resolve, reject) => {
        const terminate = fflate.unzip(data, (err, result) => {
            if (err)
                reject(err.message);
            else
                resolve(result);
        })
    });
}

/**
 * 解压缩文件，支持GZip，Zlib或DEFLATE数据
 * @param data 
 */
export function Decompress(data: Uint8Array): string | undefined {
    // decompressSync 存在eof问题
    let stringData: string | undefined = undefined;
    const utfDecode = new fflate.DecodeUTF8((data) => {
        stringData = data;
    });
    const dcmpStrm = new fflate.Decompress((chunk, final) => {
        utfDecode.push(chunk, final);
    });
    try {
        dcmpStrm.push(data);
    } catch (error) {
        console.log(error)
    }
    return stringData;
}

/**
 * 异步地解压缩文件，支持GZip，Zlib或DEFLATE数据
 * @param data 
 */
export async function DecompressAsync(data: Uint8Array, size: number | undefined = undefined): Promise<Uint8Array> {
    return new Promise<Uint8Array>((resolve, reject) => {
        const terminate = fflate.decompress(data, { size: size }, (err, result) => {
            if (err)
                reject(err.message);
            else
                resolve(result);
        });
    })
}

/**
 * 将字符串转换为8位无符号整型数组
 * @param str 
 */
export function StrToU8(str: string): Uint8Array {
    return fflate.strToU8(str);
}

/**
 * 将8位无符号整形数组转换为字符串
 * @param u8arr 
 */
export function U8ToStr(u8arr: Uint8Array): string {
    return fflate.strFromU8(u8arr);
}
